Skip to content

Commit fd066ee

Browse files
committed
Adding read/write commands.
1 parent aab775e commit fd066ee

File tree

5 files changed

+256
-38
lines changed

5 files changed

+256
-38
lines changed

app/cli-acx/src/main/java/io/github/applecommander/acx/Main.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737
import io.github.applecommander.acx.command.ListCommand;
3838
import io.github.applecommander.acx.command.LockCommand;
3939
import io.github.applecommander.acx.command.MkdirCommand;
40+
import io.github.applecommander.acx.command.ReadCommand;
4041
import io.github.applecommander.acx.command.RenameDiskCommand;
4142
import io.github.applecommander.acx.command.RenameFileCommand;
4243
import io.github.applecommander.acx.command.RmdirCommand;
4344
import io.github.applecommander.acx.command.UnlockCommand;
45+
import io.github.applecommander.acx.command.WriteCommand;
4446
import picocli.CommandLine;
4547
import picocli.CommandLine.Command;
4648
import picocli.CommandLine.HelpCommand;
@@ -69,10 +71,12 @@
6971
ListCommand.class,
7072
LockCommand.class,
7173
MkdirCommand.class,
74+
ReadCommand.class,
7275
RenameFileCommand.class,
7376
RenameDiskCommand.class,
7477
RmdirCommand.class,
75-
UnlockCommand.class
78+
UnlockCommand.class,
79+
WriteCommand.class
7680
})
7781
public class Main {
7882
private static Logger LOG = Logger.getLogger(Main.class.getName());
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* AppleCommander - An Apple ][ image utility.
3+
* Copyright (C) 2019-2022 by Robert Greene and others
4+
* robgreene at users.sourceforge.net
5+
*
6+
* This program is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License as published by the
8+
* Free Software Foundation; either version 2 of the License, or (at your
9+
* option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful, but
12+
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13+
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License along
17+
* with this program; if not, write to the Free Software Foundation, Inc.,
18+
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19+
*/
20+
package io.github.applecommander.acx.arggroup;
21+
22+
import com.webcodepro.applecommander.storage.Disk;
23+
24+
import picocli.CommandLine.ArgGroup;
25+
import picocli.CommandLine.Option;
26+
27+
public class CoordinateSelection {
28+
@ArgGroup(exclusive = false)
29+
private CoordinateSelection.SectorCoordinateSelection sectorCoordinate;
30+
@ArgGroup(exclusive = false)
31+
private CoordinateSelection.BlockCoordinateSelection blockCoordinate;
32+
33+
public byte[] read(Disk disk) {
34+
if (sectorCoordinate != null) {
35+
return sectorCoordinate.read(disk);
36+
}
37+
else if (blockCoordinate != null) {
38+
return blockCoordinate.read(disk);
39+
}
40+
return disk.readSector(0, 0);
41+
}
42+
43+
public void write(Disk disk, byte[] data) {
44+
if (sectorCoordinate != null) {
45+
sectorCoordinate.write(disk, data);
46+
}
47+
else if (blockCoordinate != null) {
48+
blockCoordinate.write(disk, data);
49+
}
50+
disk.writeSector(0, 0, data);
51+
}
52+
53+
public static class SectorCoordinateSelection {
54+
@Option(names = { "-t", "--track" }, required = true, description = "Track number.")
55+
private Integer track;
56+
@Option(names = { "-s", "--sector" }, required = true, description = "Sector number.")
57+
private Integer sector;
58+
59+
public byte[] read(Disk disk) {
60+
return disk.readSector(track, sector);
61+
}
62+
public void write(Disk disk, byte[] data) {
63+
disk.writeSector(track, sector, data);
64+
}
65+
}
66+
public static class BlockCoordinateSelection {
67+
@Option(names = { "-b", "--block" }, description = "Block number.")
68+
private Integer block;
69+
70+
public byte[] read(Disk disk) {
71+
return disk.readBlock(block);
72+
}
73+
public void write(Disk disk, byte[] data) {
74+
disk.writeBlock(block, data);
75+
}
76+
}
77+
}

app/cli-acx/src/main/java/io/github/applecommander/acx/command/DumpCommand.java

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
import java.util.function.BiFunction;
2525
import java.util.stream.Collectors;
2626

27-
import com.webcodepro.applecommander.storage.Disk;
2827
import com.webcodepro.applecommander.util.AppleUtil;
2928

29+
import io.github.applecommander.acx.arggroup.CoordinateSelection;
3030
import io.github.applecommander.acx.base.ReadOnlyDiskImageCommandOptions;
3131
import io.github.applecommander.disassembler.api.Disassembler;
3232
import io.github.applecommander.disassembler.api.Instruction;
@@ -53,42 +53,6 @@ public int handleCommand() throws Exception {
5353
return 0;
5454
}
5555

56-
public static class CoordinateSelection {
57-
@ArgGroup(exclusive = false)
58-
private SectorCoordinateSelection sectorCoordinate;
59-
@ArgGroup(exclusive = false)
60-
private BlockCoordinateSelection blockCoordinate;
61-
62-
public byte[] read(Disk disk) {
63-
if (sectorCoordinate != null) {
64-
return sectorCoordinate.read(disk);
65-
}
66-
else if (blockCoordinate != null) {
67-
return blockCoordinate.read(disk);
68-
}
69-
return disk.readSector(0, 0);
70-
}
71-
72-
public static class SectorCoordinateSelection {
73-
@Option(names = { "-t", "--track" }, required = true, description = "Track number.")
74-
private Integer track;
75-
@Option(names = { "-s", "--sector" }, required = true, description = "Sector number.")
76-
private Integer sector;
77-
78-
public byte[] read(Disk disk) {
79-
return disk.readSector(track, sector);
80-
}
81-
}
82-
public static class BlockCoordinateSelection {
83-
@Option(names = { "-b", "--block" }, description = "Block number.")
84-
private Integer block;
85-
86-
public byte[] read(Disk disk) {
87-
return disk.readBlock(block);
88-
}
89-
}
90-
}
91-
9256
public static class OutputSelection {
9357
private BiFunction<Integer,byte[],String> fn = this::formatHexDump;
9458
public String format(int address, byte[] data) {
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* AppleCommander - An Apple ][ image utility.
3+
* Copyright (C) 2019-2022 by Robert Greene and others
4+
* robgreene at users.sourceforge.net
5+
*
6+
* This program is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License as published by the
8+
* Free Software Foundation; either version 2 of the License, or (at your
9+
* option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful, but
12+
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13+
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License along
17+
* with this program; if not, write to the Free Software Foundation, Inc.,
18+
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19+
*/
20+
package io.github.applecommander.acx.command;
21+
22+
import java.io.IOException;
23+
import java.io.UncheckedIOException;
24+
import java.nio.file.Files;
25+
import java.nio.file.OpenOption;
26+
import java.nio.file.Path;
27+
import java.nio.file.StandardOpenOption;
28+
import java.util.function.Consumer;
29+
30+
import io.github.applecommander.acx.arggroup.CoordinateSelection;
31+
import io.github.applecommander.acx.base.ReadOnlyDiskImageCommandOptions;
32+
import picocli.CommandLine.ArgGroup;
33+
import picocli.CommandLine.Command;
34+
import picocli.CommandLine.Option;
35+
36+
@Command(name = "read", description = "Read a block or sector.")
37+
public class ReadCommand extends ReadOnlyDiskImageCommandOptions {
38+
@ArgGroup(multiplicity = "1", heading = "%nCoordinate Selection:%n")
39+
private CoordinateSelection coordinate = new CoordinateSelection();
40+
41+
@ArgGroup(heading = "%nOutput Selection:%n")
42+
private OutputSelection output = new OutputSelection();
43+
44+
@Option(names = { "-f", "--force" }, description = "Overwrite existing file (combine with '-o').")
45+
private void selectForceFile(boolean flag) {
46+
openOptions = new OpenOption[] { StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING,
47+
StandardOpenOption.WRITE };
48+
}
49+
private static OpenOption[] openOptions = { StandardOpenOption.CREATE_NEW };
50+
51+
@Override
52+
public int handleCommand() throws Exception {
53+
byte[] data = coordinate.read(disk);
54+
output.write(data);
55+
return 0;
56+
}
57+
58+
public static class OutputSelection {
59+
private Consumer<byte[]> sink = this::writeToStdout;
60+
private String filename;
61+
62+
public void write(byte[] data) {
63+
sink.accept(data);
64+
}
65+
66+
@Option(names = "--stdout", description = "Write raw data to stdout. (default)")
67+
public void selectStdout(boolean flag) {
68+
sink = this::writeToStdout;
69+
}
70+
@Option(names = { "-o", "--output" }, description = "Write raw data to file.")
71+
public void selectFile(String filename) {
72+
this.filename = filename;
73+
this.sink = this::writeToFile;
74+
}
75+
76+
public void writeToStdout(byte[] data) {
77+
try {
78+
System.out.write(data);
79+
} catch (IOException e) {
80+
throw new UncheckedIOException(e);
81+
}
82+
}
83+
public void writeToFile(byte[] data) {
84+
try {
85+
Files.write(Path.of(filename), data, openOptions);
86+
} catch (IOException e) {
87+
throw new UncheckedIOException(e);
88+
}
89+
}
90+
}
91+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* AppleCommander - An Apple ][ image utility.
3+
* Copyright (C) 2019-2022 by Robert Greene and others
4+
* robgreene at users.sourceforge.net
5+
*
6+
* This program is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License as published by the
8+
* Free Software Foundation; either version 2 of the License, or (at your
9+
* option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful, but
12+
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13+
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License along
17+
* with this program; if not, write to the Free Software Foundation, Inc.,
18+
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19+
*/
20+
package io.github.applecommander.acx.command;
21+
22+
import java.io.IOException;
23+
import java.io.UncheckedIOException;
24+
import java.nio.file.Files;
25+
import java.nio.file.Path;
26+
import java.util.function.Supplier;
27+
28+
import io.github.applecommander.acx.arggroup.CoordinateSelection;
29+
import io.github.applecommander.acx.base.ReadOnlyDiskImageCommandOptions;
30+
import picocli.CommandLine.ArgGroup;
31+
import picocli.CommandLine.Command;
32+
import picocli.CommandLine.Option;
33+
34+
@Command(name = "write", description = "Write a block or sector.")
35+
public class WriteCommand extends ReadOnlyDiskImageCommandOptions {
36+
@ArgGroup(multiplicity = "1", heading = "%nCoordinate Selection:%n")
37+
private CoordinateSelection coordinate = new CoordinateSelection();
38+
39+
@ArgGroup(heading = "%nInput Selection:%n")
40+
private InputSelection input = new InputSelection();
41+
42+
@Override
43+
public int handleCommand() throws Exception {
44+
byte[] data = input.read();
45+
coordinate.write(disk, data);
46+
return 0;
47+
}
48+
49+
public static class InputSelection {
50+
private Supplier<byte[]> source = this::readFromStdin;
51+
private String filename;
52+
53+
public byte[] read() {
54+
return source.get();
55+
}
56+
57+
@Option(names = "--stdin", description = "Read raw data from stdin. (default)")
58+
public void selectStdout(boolean flag) {
59+
source = this::readFromStdin;
60+
}
61+
@Option(names = { "-f", "--input" }, description = "Read raw data from file.")
62+
public void selectFile(String filename) {
63+
this.filename = filename;
64+
this.source = this::readFromFile;
65+
}
66+
67+
public byte[] readFromStdin() {
68+
try {
69+
return System.in.readAllBytes();
70+
} catch (IOException e) {
71+
throw new UncheckedIOException(e);
72+
}
73+
}
74+
public byte[] readFromFile() {
75+
try {
76+
return Files.readAllBytes(Path.of(filename));
77+
} catch (IOException e) {
78+
throw new UncheckedIOException(e);
79+
}
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)