control sequenes

This commit is contained in:
llaoj 2022-12-13 13:52:15 +08:00
parent 0620cb5c2c
commit 8450aa5ee2
2 changed files with 62 additions and 52 deletions

View File

@ -175,8 +175,9 @@ visit `http://127.0.0.1:8080/?arg=without-istio&arg=sleep-7b6d569576-57sjq&arg=s
``` ```
... ...
2022/11/13 10:48:12 [write-log] {"arg":["without-istio","sleep-7b6d569576-57sjq","sleep","21001713"]} lsCR 2022/12/13 13:36:46 [write-log] map[arg:[without-istio sleep-7b6d569576-8nz7t sleep 21001713]] ls[CR]
2022/11/13 10:48:14 [write-log] {"arg":["without-istio","sleep-7b6d569576-57sjq","sleep","21001713"]} pwdCR 2022/12/13 13:37:25 [write-log] map[arg:[without-istio sleep-7b6d569576-8nz7t sleep 21001713]] echo[SPACE]hello[SPACE]world;[CR]
2022/12/13 13:47:00 [write-log] map[arg:[without-istio sleep-7b6d569576-8nz7t sleep 21001713]] [CUU][CR]
... ...
``` ```

View File

@ -1,8 +1,11 @@
package utils package utils
import "fmt" import (
"fmt"
"regexp"
)
var CtrlChar = map[byte]string{ var ControlCodes = map[byte]string{
0: "NUL", 0: "NUL",
1: "SOH", 1: "SOH",
2: "STX", 2: "STX",
@ -39,67 +42,73 @@ var CtrlChar = map[byte]string{
127: "DEL", 127: "DEL",
} }
var CtrlCharGroup = map[string]string{ // https://en.wikipedia.org/wiki/ANSI_escape_code
"1B5B41": "UP", // https://xtermjs.org/docs/api/vtfeatures/
"1B5B42": "DOWN", var ControlSequences = map[string]string{
"1B5B43": "RIGHT", // Cursor Up
"1B5B44": "LEFT", "ESC[A": "CUU",
// Cursor Down
// shell control codes "ESC[B": "CUD",
// codes[0]+codes[1]+codes[n-1] // Cursor Forward
// for example: "ESC[C": "CUF",
// [1B(ESC) 5B([) 32(2) 3B(;) 35(5) 52(R)]: row 2 col 5 // Cursor Back
// [1B(ESC) 5B([) 31(1) 30(0) 3B(;) 35(5) 52(R)]: row 10 col 5 "ESC[D": "CUB",
// [1B(ESC) 5B([) 32(2) 32(2) 3B(;) 35(5) 52(R)]: row 22 col 5
"1B5B52": "",
// maybe there will be more control char group
// ...
} }
func FormatWriteLog(codes []byte, line *string) { var ControlSequencePatterns = map[string]string{
n := len(codes) // Device Status Report
// when user uses the keyboard arrow keys // Reports the cursor position (CPR) by transmitting `ESC[n;mR`, where n is the row and m is the column.
// arrow keys are combination of 3 ASCII codes "^ESC\\[\\d+;\\d+R$": "",
if n == 3 {
if str, exist := ASCIIGroupToStr(fmt.Sprintf("%X", codes)); exist {
*line += str
return
}
}
// for some shells
// they will automatically send some control characters
// after typing the command and pressing Enter
// which indicate the current row and column.
if n >= 6 {
if str, exist := ASCIIGroupToStr(fmt.Sprintf("%X", []byte{codes[0], codes[1], codes[n-1]})); exist {
*line += str
return
}
} }
str := ASCIIToStr(codes) func ControlCodesToStr(codes []byte) (str string) {
*line += str
return
}
func ASCIIToStr(codes []byte) (str string) {
for _, code := range codes { for _, code := range codes {
if value, ok := CtrlChar[code]; ok { if value, ok := ControlCodes[code]; ok {
str += value str += value
} else { } else {
str += string(code) str += string(code)
} }
} }
return return
} }
func ASCIIGroupToStr(group string) (string, bool) { func ControlCodesToEscapedStr(codes []byte) (str string) {
if value, ok := CtrlCharGroup[group]; ok { for _, code := range codes {
return value, true if value, ok := ControlCodes[code]; ok {
str += fmt.Sprintf("[%s]", value)
} else if code == 91 || code == 92 || code == 93 {
// escaping [ ] \
str += fmt.Sprintf("\\%s", string(code))
} else {
str += string(code)
}
}
return
} }
return "", false func ControlSequenceToStr(codes []byte) (string, bool) {
sequence := ControlCodesToStr(codes)
for key, value := range ControlSequences {
if key == sequence {
return fmt.Sprintf("[%s]", value), true
}
}
for key, value := range ControlSequencePatterns {
if regexp.MustCompile(key).Match([]byte(sequence)) {
return value, true
}
}
return sequence, false
}
func FormatWriteLog(codes []byte, line *string) {
n := len(codes)
if n >= 3 {
if str, exists := ControlSequenceToStr(codes); exists {
*line += str
return
}
}
*line += ControlCodesToEscapedStr(codes)
} }