From 98cdf435d4974f4cca8f7b4eb4026da2c88cbc4c Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Sun, 26 Mar 2017 11:30:43 -0400 Subject: Update --- .../src/main/java/bjc/utils/cli/fds/FDS.java | 69 ++++++++++ .../main/java/bjc/utils/cli/fds/FDSCommand.java | 26 ++++ .../main/java/bjc/utils/cli/fds/FDSException.java | 32 +++++ .../src/main/java/bjc/utils/cli/fds/FDSMode.java | 94 ++++++++++++++ .../main/java/bjc/utils/cli/fds/SimpleFDSMode.java | 142 +++++++++++++++++++++ 5 files changed, 363 insertions(+) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDS.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSCommand.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSException.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSMode.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/fds/SimpleFDSMode.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/cli/fds') diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDS.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDS.java new file mode 100644 index 0000000..6dc0337 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDS.java @@ -0,0 +1,69 @@ +package bjc.utils.cli.fds; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import bjc.utils.ioutils.Block; +import bjc.utils.ioutils.BlockReader; + +/** + * Runs a FDS (FDiskScript) interface. + * + * This is a rudimentary console interface inspired heavily by FDisk's interface + * style. + * + * Commands are denoted by a single character, but can invoke submodes. + * + * @author bjculkin + * + */ +public class FDS { + /** + * Run a provided FDS mode until it is exited or there is no more input. + * + * @param comin + * The command input source for the FDS mode. + * + * @param datain + * The data input source for the FDS mode. + * + * @param out + * The output source for the FDS mode. + * + * @param initialMode + * The mode to start in. + * + * @param initialState + * The initial state for the mode. + * + * @return The final state of the mode. + * + * @throws FDSException + * If something went wrong during mode execution. + */ + public static S runFDS(InputStream comin, InputStream datain, OutputStream out, FDSMode initialMode, + S initialState) throws FDSException { + PrintStream printer = new PrintStream(out); + + try (BlockReader blockSource = new BlockReader("\\R", new InputStreamReader(comin))) { + printer.print("Enter a command (m for help): "); + + while (blockSource.hasNext()) { + Block comBlock = blockSource.next(); + + String comString = comBlock.contents.trim(); + + char comChar = comString.charAt(0); + + printer.println(String.format("\nRecieved command '%s'\n", comChar)); + + printer.print("Enter a command (m for help): "); + } + } catch (Exception ex) { + throw new FDSException("Unexpected I/O error", ex); + } + + return initialState; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSCommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSCommand.java new file mode 100644 index 0000000..0a6d29c --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSCommand.java @@ -0,0 +1,26 @@ +package bjc.utils.cli.fds; + +import java.util.Iterator; + +/** + * A command attached to an FDS interface. + * + * @author bjculkin + * + * @param + * The state type of the interface. + */ +public interface FDSCommand { + /** + * Run this command. + * + * @param state + * The current FDS state. + * + * @param input + * The source for data input. + * + * @return The new state, after running the command. + */ + S run(S state, Iterator input); +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSException.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSException.java new file mode 100644 index 0000000..7569d95 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSException.java @@ -0,0 +1,32 @@ +package bjc.utils.cli.fds; + +/** + * Exception thrown when something goes wrong with FDS. + * + * @author bjculkin + * + */ +public class FDSException extends Exception { + /** + * Create a new FDS exception with a message and a cause. + * + * @param message + * The message for the exception. + * + * @param cause + * The cause of the exception. + */ + public FDSException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Create a new FDS exception with a message. + * + * @param message + * The message for the exception. + */ + public FDSException(String message) { + super(message); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSMode.java new file mode 100644 index 0000000..acdcbcb --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/FDSMode.java @@ -0,0 +1,94 @@ +package bjc.utils.cli.fds; + +import bjc.utils.cli.CommandHelp; +import bjc.utils.cli.NullHelp; + +/** + * A collection of related FDS commands. + * + * @author bjculkin + * + * @param + * The FDS state type. + */ +public interface FDSMode { + /** + * Get all the characters that are registered to something in this mode. + * + * In this context, something means a command or submode. + * + * @return All of the characters registered to something in this mode. + */ + char[] registeredChars(); + + /* + * Check for the existence of commands/submodes. + */ + + /** + * Check if there is a command registered to the given character. + * + * @param c + * The character to check + * + * @return Whether or not there is a command bound to that character. + */ + boolean hasCommand(char c); + + /** + * Check if there is a submode registered to the given character. + * + * @param c + * The character to check + * + * @return Whether or not there is a submode bound to that character. + */ + boolean hasSubmode(char c); + + /* + * Get commands and submodes. + */ + + /** + * Get the command attached to a given character. + * + * @param c + * The character to get the command for. + * + * @return The command bound to that character. + * + * @throws FDSException + * If there is no command bound to that character. + */ + FDSCommand getCommand(char c) throws FDSException; + + /** + * Get the command attached to a given character. + * + * @param c + * The character to get the command for. + * + * @return The command bound to that character. + * + * @throws FDSException + * If there is no command bound to that character. + */ + FDSMode getSubmode(char c) throws FDSException; + + /* + * Help utilities + */ + /** + * Get the help for what's bound to a character. + * + * This should be one line. + * + * @param c + * The character to look at the help for. + * + * @return The help for what's bound to the character. + */ + default CommandHelp getHelp(char c) { + return new NullHelp(); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/fds/SimpleFDSMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/SimpleFDSMode.java new file mode 100644 index 0000000..2f6e660 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/fds/SimpleFDSMode.java @@ -0,0 +1,142 @@ +package bjc.utils.cli.fds; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import bjc.utils.cli.CommandHelp; + +import static java.lang.String.format; + +/** + * Simple implementation of {@link FDSMode}. + * + * @author bjculkin + * + * @param + * The FDS state type. + */ +public class SimpleFDSMode implements FDSMode { + private Map> commands; + private Map> modes; + private Map help; + + private Set registered; + private char[] registeredArray; + private boolean changed; + + /** + * Create a new empty FDS mode. + */ + public SimpleFDSMode() { + commands = new HashMap<>(); + modes = new HashMap<>(); + help = new HashMap<>(); + + registered = new HashSet<>(); + changed = true; + } + + /** + * Add a command to the mode. + * + * @param c + * The character to bind to the command. + * + * @param comm + * The command to add. + * + * @param hlp + * The help for the command. + * + * @throws FDSException + * If the character is already bound to a command. + */ + public void addCommand(char c, FDSCommand comm, CommandHelp hlp) throws FDSException { + if (comm == null) + throw new NullPointerException("Command must not be null"); + else if (commands.containsKey(c) || modes.containsKey(c)) + throw new FDSException(format("Character '%s' is already bound")); + + commands.put(c, comm); + + registered.add(c); + if (!changed) changed = true; + } + + /** + * Add a submode to the mode. + * + * @param c + * The character to bind to the submode. + * + * @param mode + * The submode to add. + * + * @throws FDSException + * If the character is already bound to a submode. + */ + public void addSubmode(char c, FDSMode mode) throws FDSException { + if (mode == null) + throw new NullPointerException("Mode must not be null"); + else if (modes.containsKey(c) || commands.containsKey(c)) + throw new FDSException(format("Character '%s' is already bound")); + + modes.put(c, mode); + + registered.add(c); + if (!changed) changed = true; + } + + @Override + public char[] registeredChars() { + if (!changed) return registeredArray; + + registeredArray = new char[registered.size()]; + + int i = 0; + for (char c : registered) { + registeredArray[i] = c; + + i += 1; + } + + changed = false; + + return registeredArray; + } + + @Override + public boolean hasCommand(char c) { + return commands.containsKey(c); + } + + @Override + public boolean hasSubmode(char c) { + return modes.containsKey(c); + } + + @Override + public FDSCommand getCommand(char c) throws FDSException { + if (!commands.containsKey(c)) { + throw new FDSException(String.format("No command bound to '%s'", c)); + } + + return commands.get(c); + } + + @Override + public FDSMode getSubmode(char c) throws FDSException { + if (!modes.containsKey(c)) { + throw new FDSException(String.format("No mode bound to '%s'", c)); + } + + return modes.get(c); + } + + @Override + public CommandHelp getHelp(char c) { + return help.get(c); + } +} \ No newline at end of file -- cgit v1.2.3