296 lines
11 KiB
Java
296 lines
11 KiB
Java
package Common.Utils.Validators;
|
||
import Common.Constants;
|
||
import Common.Global;
|
||
import Common.Utils.Utils;
|
||
|
||
import java.io.InputStreamReader;
|
||
import java.util.Vector;
|
||
public class ShellParser {
|
||
public static ShellParserState state;
|
||
public static StringBuilder lineBuilder;
|
||
public static String userName;
|
||
public static StringBuilder invitationBuilder;
|
||
public static char c;
|
||
public static char[] buffer = new char[1];
|
||
public static Vector<String> lines = new Vector<>();
|
||
// public static boolean bracketOpened = false;
|
||
public static boolean return_active = false;
|
||
public static boolean isCommandSymbol() {
|
||
int code = c;
|
||
return code <= 31 || c == 127;
|
||
}
|
||
public static void ResetLine() {
|
||
invitationBuilder = new StringBuilder();
|
||
lineBuilder = new StringBuilder();
|
||
// bracketOpened = false;
|
||
state = ShellParserState.NewLine;
|
||
return_active = false;
|
||
}
|
||
public static boolean isNameCharacter() {
|
||
//латиница, цифры,подчеркивания. и -
|
||
return String.valueOf(c).matches("[\\w\\-]*") || c == '?';
|
||
}
|
||
public static boolean isRBracket(){
|
||
return c=='('||c==')';
|
||
}
|
||
|
||
//false наоборот означать что конец строки ЕСТЬ.
|
||
public static boolean checkEndLine() {
|
||
if (return_active) {
|
||
switch (c) {
|
||
case '\n':
|
||
//ложная тревога. возврат каретки ни на что не влияет.
|
||
lines.add(lineBuilder.toString());
|
||
ResetLine();
|
||
return false;
|
||
case '\r':
|
||
return false;
|
||
default:
|
||
//тут был возврат. надо игнорить символ, ибо он уже прочитан.
|
||
return_active = false;
|
||
return false;
|
||
}
|
||
} else {
|
||
switch (c) {
|
||
case '\r':
|
||
return_active = true;
|
||
return false;
|
||
case '\n':
|
||
lines.add(lineBuilder.toString());
|
||
ResetLine();
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
/*
|
||
public static void NewLine() {
|
||
if (c == '[') {//приглашение со скобками.
|
||
// bracketOpened = true;
|
||
invitationBuilder.append(c);
|
||
state = ShellParserState.UserName;
|
||
} else {
|
||
if (isNameCharacter()) {
|
||
invitationBuilder.append(c);
|
||
state = ShellParserState.UserName;
|
||
} else
|
||
//не буква и не скобка. значит в этой строке приглашения нет.
|
||
state = ShellParserState.Skip;
|
||
}
|
||
}
|
||
*/
|
||
public static void NewLine() {
|
||
if (c=='@'){ //собака, признак приглашения.
|
||
String test = invitationBuilder.toString();
|
||
test = test.toLowerCase();
|
||
state = test.endsWith(userName.toLowerCase()) ? ShellParserState.MachineName : ShellParserState.Skip;
|
||
invitationBuilder.append(c);
|
||
}else {
|
||
invitationBuilder.append(c);
|
||
}
|
||
/*
|
||
if (c == '[') {//приглашение со скобками.
|
||
// bracketOpened = true;
|
||
invitationBuilder.append(c);
|
||
state = ShellParserState.UserName;
|
||
} else {
|
||
if (isNameCharacter()) {
|
||
invitationBuilder.append(c);
|
||
state = ShellParserState.UserName;
|
||
} else
|
||
//не буква и не скобка. значит в этой строке приглашения нет.
|
||
state = ShellParserState.Skip;
|
||
}
|
||
*/
|
||
}
|
||
/*
|
||
public static void UserName() {
|
||
if (c == '@') { //проверить. а тот ли юзернейм.
|
||
String test = invitationBuilder.toString();
|
||
// if (bracketOpened) test = test.substring(1);
|
||
test = test.toLowerCase();
|
||
state = test.endsWith(userName.toLowerCase()) ? ShellParserState.MachineName : ShellParserState.Skip;
|
||
invitationBuilder.append(c);
|
||
} else if (isNameCharacter() || (c == '['))
|
||
invitationBuilder.append(c);
|
||
else
|
||
state = ShellParserState.Skip;
|
||
}
|
||
*/
|
||
public static void MachineName() {
|
||
switch (c) {
|
||
case ' ':
|
||
case ':':
|
||
state = ShellParserState.Path;
|
||
invitationBuilder.append(c);
|
||
break;
|
||
default:
|
||
if (isNameCharacter())
|
||
invitationBuilder.append(c);
|
||
else state = ShellParserState.Skip;
|
||
break;
|
||
}
|
||
}
|
||
public static void Path() {
|
||
switch (c) {
|
||
case '$':
|
||
case '#':
|
||
case '>':
|
||
invitationBuilder.append(c);
|
||
state = ShellParserState.Space; //приглашение завершено. осталось прочитать пробел после него
|
||
break;
|
||
/*
|
||
case ']':
|
||
if (bracketOpened) {
|
||
invitationBuilder.append(c);
|
||
bracketOpened = false;
|
||
} else {
|
||
// UI.Info("KEK");
|
||
state = ShellParserState.Skip; //непарная скобка, все, привет
|
||
}
|
||
break;
|
||
*/
|
||
default:
|
||
invitationBuilder.append(c);
|
||
break;
|
||
}
|
||
}
|
||
public static void Space() {
|
||
if (c == ' ') {
|
||
state = ShellParserState.End;
|
||
invitationBuilder.append(c);
|
||
} else {
|
||
state = ShellParserState.Skip;
|
||
}
|
||
}
|
||
public static void setUserName(String userName_in) {
|
||
userName = userName_in;
|
||
}
|
||
public static void printChar() {
|
||
if (c != Constants.boop) {
|
||
int code = c;
|
||
if ((!return_active) || (c == '\n')) {
|
||
System.out.print(c == '\r' ? ("\\r") :
|
||
(c == '\n' ? "\\n\n" : c));
|
||
if (isCommandSymbol())
|
||
System.out.print(Utils.RBrackets(code));
|
||
}
|
||
}
|
||
}
|
||
public static void ReadInvitation(InputStreamReader fromServer) {
|
||
lines.clear();
|
||
ResetLine();
|
||
do {
|
||
try {
|
||
if (fromServer.read(buffer) >= 0) {
|
||
c = buffer[0];
|
||
printChar();
|
||
// if (!isCommandSymbol()) {
|
||
if (checkEndLine() && (!isCommandSymbol())) {
|
||
lineBuilder.append(c);
|
||
switch (state) {
|
||
case NewLine:
|
||
NewLine();
|
||
break;
|
||
// case UserName:
|
||
// UserName();
|
||
// break;
|
||
case MachineName:
|
||
MachineName();
|
||
break;
|
||
case Path:
|
||
Path();
|
||
break;
|
||
case Space:
|
||
Space();
|
||
break;
|
||
case Skip:
|
||
break;
|
||
}
|
||
}
|
||
// System.out.println(Utils.Brackets(state));
|
||
// }
|
||
} else
|
||
state = ShellParserState.End;
|
||
} catch (Exception ex) {
|
||
Global.Log.PrintException(ex);
|
||
state = ShellParserState.End;
|
||
}
|
||
} while (!state.equals(ShellParserState.End));
|
||
}
|
||
public static String ReadLine(InputStreamReader fromServer) {
|
||
StringBuilder res = new StringBuilder();
|
||
state = ShellParserState.NewLine;
|
||
do {
|
||
try {
|
||
if (fromServer.read(buffer) >= 0) {
|
||
c = buffer[0];
|
||
printChar();
|
||
switch (c) {
|
||
case '\r':
|
||
break;
|
||
case '\n':
|
||
state = ShellParserState.End;
|
||
break;
|
||
default:
|
||
res.append(c);
|
||
break;
|
||
}
|
||
} else
|
||
state = ShellParserState.End;
|
||
} catch (Exception ex) {
|
||
Global.Log.PrintException(ex);
|
||
state = ShellParserState.End;
|
||
}
|
||
} while (!state.equals(ShellParserState.End));
|
||
return res.toString();
|
||
}
|
||
public static void ReadCommand(String command, InputStreamReader fromServer){
|
||
StringBuilder res = new StringBuilder();
|
||
do {
|
||
try {
|
||
if (fromServer.read(buffer) >= 0) {
|
||
c = buffer[0];
|
||
printChar();
|
||
switch (c) {
|
||
case '\r':
|
||
break;
|
||
case '\n':
|
||
break;
|
||
default:
|
||
res.append(c);
|
||
break;
|
||
}
|
||
} else
|
||
return;
|
||
} catch (Exception ex) {
|
||
Global.Log.PrintException(ex);
|
||
return;
|
||
}
|
||
} while (!res.toString().contains(command));
|
||
}
|
||
public static String getCommandResult(InputStreamReader fromServer) {
|
||
//если последняя строка ответа - кончается на приглашение, то ничего не делаем.
|
||
//если нет. значит ответ кончается на перевод строки. или пуст.
|
||
// нужно прочитать еще одно приглашение.
|
||
String last_line = "";
|
||
String res = "";
|
||
boolean no_extra_read = false;
|
||
if (lines.size() > 0) {
|
||
last_line = lines.lastElement();
|
||
if (no_extra_read = last_line.endsWith(invitationBuilder.toString())) {
|
||
System.out.println("needs trim");
|
||
lines.remove(lines.size() - 1);
|
||
//больше ничего не читаем. но. обрезаем ее конец.
|
||
last_line = last_line.substring(0, last_line.length() - invitationBuilder.length());
|
||
lines.add(last_line);
|
||
}
|
||
res = String.join("\n", lines);
|
||
}
|
||
if (!no_extra_read) {
|
||
ReadInvitation(fromServer);
|
||
}
|
||
return res;
|
||
}
|
||
}
|