📄 inputline.java
字号:
/** * simulator/InputLine.java */package simulator;import java.util.ArrayList;import util.CommandStatus;import util.Verbose;/** * */public class InputLine{ private Network network = null; private String parentPath; private boolean isEmpty = true; private boolean isComment = false; private boolean isCorrect = true; private boolean hasTime = false; private boolean hasCommand = false; private String line = null; private int lineLength = 0; private double lineTime = -1; private int nextFieldIdx = 0; private String lineCommand = null; private ArrayList<ArrayList<String>> lineCommandArgs = null; public boolean isEmpty() { return isEmpty; } public boolean isComment() { return isComment; } public boolean isCorrect() { return isCorrect; } public boolean hasTime() { return hasTime; } public boolean hasCommand() { return hasCommand; } public String command() { return lineCommand; } public ArrayList<ArrayList<String>> commandArgs() { return lineCommandArgs; } public double time() { return lineTime; } public InputLine(Network net, String path, String str) { network = net; parentPath = path; line = str.trim(); lineLength = line.length(); if (lineLength > 0) { isEmpty = false; if (line.charAt(0) == '#') { isComment = true; } else if (line.charAt(0) == '@') { hasTime = true; } else { hasCommand = true; } } if (isCorrect && hasTime) { parseTime(); } if (isCorrect && hasCommand) { parseCommand(); } if (isCorrect && hasCommand && (lineCommand == null || lineCommand.length() < 1)) { hasCommand = false; } if (net.vShouldLog(Verbose.DEBUG6)) net.vprint(debugString()); } public String toString() { return line; } public String debugString() { return "INPUT_LINE: '" + line + "'; isEmpty: " + isEmpty + "; isComment: " + isComment + "; isCorrect: " + isCorrect + "; hasTime: " + hasTime + "; hasCommand: " + hasCommand + "; time: " + lineTime + "; Command: " + lineCommand + "; CommandArgs: " + lineCommandArgs; } public CommandStatus execCommand() { if (!hasCommand() || isEmpty()) return null; if (lineCommand == null || lineCommand.length() < 1) { hasCommand = false; return null; } CommandStatus cs; cs = network.parseLocalCommand(lineCommand, lineCommandArgs, parentPath); if (cs != null) return cs; cs = parseNodeCommand(); if (cs != null) return cs; cs = parseContactCommand(); if (cs != null) return cs; if (lineCommand.equals("echo")) { String tmp = line.toLowerCase(); int idx = tmp.indexOf("echo"); if (idx >= 0) { if (idx + 5 < line.length()) { System.out.println(line.substring(idx + 5)); } else { System.out.println(); } return new CommandStatus(CommandStatus.COMMAND_OK); } } // Now, even if it was not handled - we don't care return cs; } private CommandStatus parseNodeCommand() { if (lineCommand.length() > 1 && lineCommand.charAt(0) == '$') { String nName = lineCommand.substring(1); Node n = network.getNode(nName); if (n != null) { return n.parseLocalCommand(lineCommand, lineCommandArgs, parentPath); } return new CommandStatus("Could not find/create node '" + nName + "'!"); } else if (lineCommand.equals("default_node")) { return network.getDefaultNode().parseLocalCommand(lineCommand, lineCommandArgs, parentPath); } return null; } public ArrayList<Contact> findContactsForCommand() { if (!isCorrect || !hasCommand) return null; ArrayList<Contact> ret = new ArrayList<Contact>(); if (lineCommand.equals("default_contact")) { ret.add(network.getDefaultContact()); return ret; } ArrayList<String> nodeNames = parseContactName(lineCommand); if (nodeNames != null && nodeNames.size() > 0) { int i, s = nodeNames.size(); for (i = 2; i < s; i += 3) { Contact c = network.getContact(nodeNames.get(i - 2), nodeNames.get(i - 1), nodeNames.get(i)); if (c != null) { ret.add(c); } } assert i == s + 2; } return ret; } private CommandStatus parseContactCommand() { ArrayList<Contact> contacts = findContactsForCommand(); boolean wasOk = false; int i, s = contacts.size(); for (i = 0; i < s; ++i) { Contact c = contacts.get(i); CommandStatus ret = null; if (c != null) { ret = c.parseLocalCommand(lineCommand, lineCommandArgs, parentPath); } else { return new CommandStatus("Could not find/create contact for '" + lineCommand + "'!"); } if (ret != null) { if (ret.commandStatus == CommandStatus.COMMAND_FAILED) return ret; if (ret.commandStatus == CommandStatus.COMMAND_OK) wasOk = true; } } if (wasOk) return new CommandStatus(CommandStatus.COMMAND_OK); return null; } private ArrayList<String> parseContactName(String str) { int l = str.length(); if (Character.isLetterOrDigit(str.charAt(0)) && Character.isLetterOrDigit(str.charAt(l - 1)) && (str.contains("<->") || str.contains("->") || str.contains("<-"))) { ArrayList<String> ret = new ArrayList<String>(6); int symA = 0, symB = 0, symC = 0, symD = 0; for (int i = 0; i < l; ++i) { switch (str.charAt(i)) { case '<': ++symA; break; case '-': ++symB; break; case '>': ++symC; break; case ':': ++symD; break; } } if (symA > 1 || symB > 1 || symC > 1 || symD > 1) { ret.add("Wrong contact specification! Too many '<->:' " + "characters i contact name '" + str + "'!"); return ret; } assert symB == 1 && symA + symC > 0; String nodeA = null, nodeB = null, cName = null; boolean bidir = false; if (symD > 0) { int idx = str.indexOf(':'); cName = str.substring(idx + 1); str = str.substring(0, idx); } else { cName = ""; } // <-> => A->B B->A if (symA == 1 && symC == 1) { bidir = true; nodeA = str.substring(0, str.indexOf('<')); nodeB = str.substring(str.lastIndexOf('>') + 1, str.length()); } // B<-A else if (symA == 1) { nodeA = str.substring(str.lastIndexOf('-') + 1, str.length()); nodeB = str.substring(0, str.indexOf('<')); } // A->B else if (symC == 1) { nodeA = str.substring(0, str.indexOf('-')); nodeB = str.substring(str.lastIndexOf('>') + 1, str.length()); } if (nodeA == null || nodeB == null) { ret.add("Wrong contact specification!"); return ret; } ret.add(nodeA); ret.add(nodeB); ret.add(cName); if (bidir) { ret.add(nodeB); ret.add(nodeA); ret.add(cName); } return ret; } return null; } private void parseTime() { assert hasTime : "parseTime on Input Line with hasTime == false!"; int i; boolean wasDot = false; boolean isRelative = false; if (lineLength >= 4 && line.substring(1, 4).equalsIgnoreCase("end") && (lineLength == 4 || Character.isWhitespace(line.charAt(4)))) { lineTime = Double.POSITIVE_INFINITY; isCorrect = true; nextFieldIdx = 4; if (lineLength > 4) hasCommand = true; return; } int beg = 1; if (line.charAt(1) == '+') { ++beg; isRelative = true; } for (i = beg; i < lineLength; ++i) { if (line.charAt(i) == '.') { if (wasDot) { nextFieldIdx = i; isCorrect = false; hasTime = false; break; } wasDot = true; } else if (!Character.isDigit(line.charAt(i))) { nextFieldIdx = i; break; } } if (i >= lineLength) { nextFieldIdx = lineLength; } else { hasCommand = true; } if (i > beg) { try { lineTime = Double.parseDouble(line.substring(beg, nextFieldIdx)); if (isRelative) { lineTime += network.getCurrentTime(); } } catch (NumberFormatException e) { isCorrect = false; } } else { isCorrect = false; } } private void parseCommand() { assert hasCommand : "parseCommand on Input Line with hasCommand == false!"; String field; boolean wasEq = false; boolean checkCName = true; boolean completeCName = false; lineCommandArgs = new ArrayList<ArrayList<String>>(); lineCommand = null; while ((field = getNextField()) != null) { if (field.length() == 1 && field.charAt(0) == '=') { wasEq = true; if (lineCommandArgs.size() < 1) { isCorrect = false; return; } } else { if (wasEq) { int s = lineCommandArgs.size(); assert s > 0; lineCommandArgs.get(s - 1).add(field); } else { if (lineCommand == null) { lineCommand = field; // If the end of first field in command line is -> or <- // it means that it is probably a contact name with a // whitechar(s) inside, and we want to concat next field if (lineCommand.endsWith("->") || lineCommand.endsWith("<-")) { completeCName = true; } } else { if (completeCName) { lineCommand = lineCommand.concat(field); completeCName = false; checkCName = false; continue; } if (checkCName && (field.startsWith("<-") || field.startsWith("->"))) { lineCommand = lineCommand.concat(field); if (lineCommand.endsWith("->") || lineCommand.endsWith("<-")) { completeCName = true; } checkCName = false; continue; } checkCName = false; // Most of arguments have 2 parts: param_name and // param_value ArrayList<String> vs = new ArrayList<String>(2); vs.add(field.toLowerCase()); lineCommandArgs.add(vs); } } wasEq = false; } } lineCommandArgs.trimToSize(); } private String getNextField() { while (nextFieldIdx < lineLength && Character.isWhitespace(line.charAt(nextFieldIdx))) ++nextFieldIdx; if (nextFieldIdx >= lineLength) return null; if (line.charAt(nextFieldIdx) == '=') { ++nextFieldIdx; return new String("="); } int sIdx = nextFieldIdx; while (nextFieldIdx < lineLength && !(Character.isWhitespace(line.charAt(nextFieldIdx)) || line.charAt(nextFieldIdx) == '=')) { ++nextFieldIdx; } if (nextFieldIdx <= sIdx) return null; return line.substring(sIdx, nextFieldIdx); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -