github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/queryparser/classic/fastCharStream.go (about)

     1  package classic
     2  
     3  import (
     4  	"io"
     5  )
     6  
     7  type FastCharStream struct {
     8  	buffer []rune
     9  
    10  	bufferLength   int
    11  	bufferPosition int
    12  
    13  	tokenStart  int
    14  	bufferStart int
    15  
    16  	input io.RuneReader // source of chars
    17  }
    18  
    19  func newFastCharStream(r io.RuneReader) *FastCharStream {
    20  	return &FastCharStream{input: r}
    21  }
    22  
    23  func (cs *FastCharStream) readChar() (rune, error) {
    24  	if cs.bufferPosition >= cs.bufferLength {
    25  		if err := cs.refill(); err != nil {
    26  			return 0, err
    27  		}
    28  	}
    29  	cs.bufferPosition++
    30  	return cs.buffer[cs.bufferPosition-1], nil
    31  }
    32  
    33  func (cs *FastCharStream) refill() (err error) {
    34  	newPosition := cs.bufferLength - cs.tokenStart
    35  
    36  	if cs.tokenStart == 0 { // token won't fit in buffer
    37  		if cs.buffer == nil { // first time: alloc buffer
    38  			cs.buffer = make([]rune, 2048)
    39  		} else if cs.bufferLength == len(cs.buffer) { // grow buffer
    40  			assert(cs.bufferLength < 1000000) // should not be that large
    41  			newBuffer := make([]rune, len(cs.buffer)*2)
    42  			copy(newBuffer, cs.buffer)
    43  			cs.buffer = newBuffer
    44  		}
    45  	} else { // shift token to front
    46  		copy(cs.buffer, cs.buffer[cs.tokenStart:cs.tokenStart+newPosition])
    47  	}
    48  
    49  	cs.bufferLength = newPosition // update state
    50  	cs.bufferPosition = newPosition
    51  	cs.bufferStart += cs.tokenStart
    52  	cs.tokenStart = 0
    53  
    54  	var charsRead int // fill space in buffer
    55  	limit := len(cs.buffer) - newPosition
    56  	for charsRead < limit && err == nil {
    57  		cs.buffer[newPosition+charsRead], _, err = cs.input.ReadRune()
    58  		if err == nil {
    59  			charsRead++
    60  		}
    61  	}
    62  	if err != nil && err != io.EOF || charsRead == 0 {
    63  		return err
    64  	}
    65  	cs.bufferLength += charsRead
    66  	return nil
    67  }
    68  
    69  func (cs *FastCharStream) beginToken() (rune, error) {
    70  	cs.tokenStart = cs.bufferPosition
    71  	return cs.readChar()
    72  }
    73  
    74  func (cs *FastCharStream) backup(amount int) {
    75  	cs.bufferPosition -= amount
    76  }
    77  
    78  func (cs *FastCharStream) image() string {
    79  	return string(cs.buffer[cs.tokenStart:cs.bufferPosition])
    80  }
    81  
    82  func (cs *FastCharStream) endColumn() int {
    83  	return cs.bufferStart + cs.bufferPosition
    84  }
    85  
    86  func (cs *FastCharStream) endLine() int {
    87  	return 1
    88  }
    89  
    90  func (cs *FastCharStream) beginColumn() int {
    91  	return cs.bufferStart + cs.tokenStart
    92  }
    93  
    94  func (cs *FastCharStream) beginLine() int {
    95  	return 1
    96  }