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 }