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  }