github.com/sijibomii/docker@v0.0.0-20231230191044-5cf6ca554647/pkg/term/windows/ansi_writer.go (about) 1 // +build windows 2 3 package windows 4 5 import ( 6 "io/ioutil" 7 "os" 8 9 ansiterm "github.com/Azure/go-ansiterm" 10 "github.com/Azure/go-ansiterm/winterm" 11 "github.com/Sirupsen/logrus" 12 ) 13 14 var logger *logrus.Logger 15 16 // ansiWriter wraps a standard output file (e.g., os.Stdout) providing ANSI sequence translation. 17 type ansiWriter struct { 18 file *os.File 19 fd uintptr 20 infoReset *winterm.CONSOLE_SCREEN_BUFFER_INFO 21 command []byte 22 escapeSequence []byte 23 inAnsiSequence bool 24 parser *ansiterm.AnsiParser 25 } 26 27 func newAnsiWriter(nFile int) *ansiWriter { 28 logFile := ioutil.Discard 29 30 if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { 31 logFile, _ = os.Create("ansiReaderWriter.log") 32 } 33 34 logger = &logrus.Logger{ 35 Out: logFile, 36 Formatter: new(logrus.TextFormatter), 37 Level: logrus.DebugLevel, 38 } 39 40 file, fd := winterm.GetStdFile(nFile) 41 info, err := winterm.GetConsoleScreenBufferInfo(fd) 42 if err != nil { 43 return nil 44 } 45 46 parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file)) 47 logger.Infof("newAnsiWriter: parser %p", parser) 48 49 aw := &ansiWriter{ 50 file: file, 51 fd: fd, 52 infoReset: info, 53 command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH), 54 escapeSequence: []byte(ansiterm.KEY_ESC_CSI), 55 parser: parser, 56 } 57 58 logger.Infof("newAnsiWriter: aw.parser %p", aw.parser) 59 logger.Infof("newAnsiWriter: %v", aw) 60 return aw 61 } 62 63 func (aw *ansiWriter) Fd() uintptr { 64 return aw.fd 65 } 66 67 // Write writes len(p) bytes from p to the underlying data stream. 68 func (aw *ansiWriter) Write(p []byte) (total int, err error) { 69 if len(p) == 0 { 70 return 0, nil 71 } 72 73 logger.Infof("Write: % x", p) 74 logger.Infof("Write: %s", string(p)) 75 return aw.parser.Parse(p) 76 }