github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/drivers/cga/ansi.go (about) 1 package cga 2 3 import ( 4 "bytes" 5 "errors" 6 ) 7 8 const ( 9 stateBegin = iota 10 stateESC 11 stateLeft 12 stateParam 13 stateDone 14 ) 15 16 const ( 17 _ESC = 0x1b 18 ) 19 20 var ( 21 errInvalidChar = errors.New("invalid char") 22 errNormalChar = errors.New("normal char") 23 errCSIDone = errors.New("done") 24 ) 25 26 type ansiParser struct { 27 state int 28 29 action byte 30 parambuf []byte 31 params []string 32 } 33 34 func (p *ansiParser) step(ch byte) error { 35 switch p.state { 36 case stateBegin: 37 if ch != _ESC { 38 return errNormalChar 39 } 40 p.state = stateESC 41 case stateESC: 42 if ch != '[' { 43 return errInvalidChar 44 } 45 p.state = stateLeft 46 case stateLeft: 47 switch { 48 case ch >= 0x30 && ch <= 0x3f: 49 p.state = stateParam 50 p.parambuf = append(p.parambuf, ch) 51 case ch >= 0x40 && ch <= 0x7f: 52 p.action = ch 53 p.state = stateDone 54 default: 55 return errInvalidChar 56 } 57 case stateParam: 58 switch { 59 case ch >= 0x30 && ch <= 0x3f: 60 p.parambuf = append(p.parambuf, ch) 61 case ch >= 0x40 && ch <= 0x7f: 62 p.action = ch 63 p.state = stateDone 64 default: 65 return errInvalidChar 66 } 67 } 68 if p.state == stateDone { 69 p.decodePram() 70 return errCSIDone 71 } 72 return nil 73 } 74 75 func (p *ansiParser) decodePram() { 76 if len(p.parambuf) == 0 { 77 return 78 } 79 params := bytes.Split(p.parambuf, []byte(";")) 80 for _, param := range params { 81 p.params = append(p.params, string(param)) 82 } 83 } 84 85 func (p *ansiParser) Action() byte { 86 return p.action 87 } 88 89 func (p *ansiParser) Params() []string { 90 return p.params 91 } 92 93 func (p *ansiParser) Reset() { 94 p.state = stateBegin 95 p.action = 0 96 p.parambuf = p.parambuf[:0] 97 p.params = p.params[:0] 98 }