Files
VisualSapfor/src/Common/Utils/Validators/ShellParser.java

230 lines
8.5 KiB
Java
Raw Normal View History

2023-09-17 22:13:42 +03:00
package Common.Utils.Validators;
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 == '?';
}
//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 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() {
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 void ReadLine(InputStreamReader fromServer) {
state = ShellParserState.NewLine;
do {
try {
if (fromServer.read(buffer) >= 0) {
c = buffer[0];
printChar();
switch (c) {
case '\r':
break;
case '\n':
return;
}
} else
state = ShellParserState.End;
} catch (Exception ex) {
Global.Log.PrintException(ex);
state = ShellParserState.End;
}
} while (!state.equals(ShellParserState.End));
}
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;
}
}