github.com/informationsea/shellflow@v0.1.3/flowscript/flowscript_lookahead.go (about) 1 package flowscript 2 3 import ( 4 "bufio" 5 "container/list" 6 ) 7 8 type LookAheadScanner struct { 9 scanner *bufio.Scanner 10 lookAhead *list.List 11 lastestError error 12 firstScan bool 13 } 14 15 func NewLookAheadScanner(scanner *bufio.Scanner) *LookAheadScanner { 16 return &LookAheadScanner{ 17 scanner: scanner, 18 lookAhead: list.New(), 19 lastestError: nil, 20 firstScan: true, 21 } 22 } 23 24 func (s *LookAheadScanner) Bytes() []byte { 25 if s.lookAhead.Len() != 0 { 26 if v, ok := s.lookAhead.Front().Value.([]byte); ok { 27 return v 28 } 29 panic("Bad type") 30 } 31 return nil 32 } 33 34 func (s *LookAheadScanner) Text() string { 35 return string(s.Bytes()) 36 } 37 38 func (s *LookAheadScanner) Scan() bool { 39 if s.lastestError != nil { 40 return false 41 } 42 43 if s.lookAhead.Len() > 0 && !s.firstScan { 44 s.lookAhead.Remove(s.lookAhead.Front()) 45 } 46 47 s.firstScan = false 48 49 if s.lookAhead.Len() == 0 { 50 if !s.scanner.Scan() { 51 s.lastestError = s.Err() 52 return false 53 } 54 s.lookAhead.PushBack(s.scanner.Bytes()) 55 } 56 return true 57 } 58 59 func (s *LookAheadScanner) LookAheadBytes(i int) []byte { 60 if s.lastestError != nil { 61 return nil 62 } 63 64 for s.lookAhead.Len() < (i + 1) { 65 if !s.scanner.Scan() { 66 s.lastestError = s.Err() 67 return nil 68 } 69 s.lookAhead.PushBack(s.scanner.Bytes()) 70 } 71 72 v := s.lookAhead.Front() 73 for j := 0; j < i; j++ { 74 v = v.Next() 75 } 76 77 if b, ok := v.Value.([]byte); ok { 78 return b 79 } 80 81 panic("bad type") 82 } 83 84 func (s *LookAheadScanner) LookAheadText(i int) string { 85 return string(s.LookAheadBytes(i)) 86 } 87 88 func (s *LookAheadScanner) Err() error { 89 return s.lastestError 90 }