github.com/jmigpin/editor@v1.6.0/util/parseutil/scannerr.go (about)

     1  package parseutil
     2  
     3  import (
     4  	"github.com/jmigpin/editor/util/iout/iorw"
     5  	"github.com/jmigpin/editor/util/mathutil"
     6  )
     7  
     8  // scanner wrapper to be use with iorw.ReaderAt. Needed because the scanner deals with a []byte src, and the position starts at zero. While the reader first position is at r.Min(), where reading a position less then r.Min() gives error.
     9  type ScannerR struct {
    10  	*Scanner
    11  	R iorw.ReaderAt
    12  }
    13  
    14  func NewScannerR(r iorw.ReaderAt, index int) *ScannerR {
    15  	sc := &ScannerR{R: r}
    16  	sc.Scanner = NewScanner()
    17  
    18  	src, err := iorw.ReadFastFull(sc.R)
    19  	if err != nil {
    20  		return sc // empty scanner, no error (nothing todo, best effort)
    21  	}
    22  	sc.Scanner.SetSrc(src)
    23  
    24  	sc.SetPos(index)
    25  
    26  	return sc
    27  }
    28  func (sc *ScannerR) SetPos(v int) {
    29  	u := v - sc.R.Min()
    30  	sc.Scanner.Pos = mathutil.Limit(u, 0, len(sc.Scanner.Src))
    31  }
    32  func (sc *ScannerR) Pos() int {
    33  	return sc.R.Min() + sc.Scanner.Pos
    34  }
    35  func (sc *ScannerR) KeepPos() ScannerRPos {
    36  	return ScannerRPos{sc: sc, Pos: sc.Pos()}
    37  }
    38  
    39  func (sc *ScannerR) Src(donotuse int)    { panic("!") }
    40  func (sc *ScannerR) SetSrc(donotuse int) { panic("!") }
    41  
    42  //----------
    43  //----------
    44  //----------
    45  
    46  type ScannerRPos struct {
    47  	sc  *ScannerR
    48  	Pos int
    49  }
    50  
    51  func (sp *ScannerRPos) Restore() {
    52  	sp.sc.SetPos(sp.Pos)
    53  }
    54  func (sp *ScannerRPos) IsEmpty() bool {
    55  	return sp.Pos == sp.sc.Pos()
    56  }
    57  func (sp *ScannerRPos) StartEnd() (int, int) {
    58  	start, end := sp.Pos, sp.sc.Pos()
    59  	if start > end { // support reverse mode
    60  		start, end = end, start
    61  	}
    62  	return start, end
    63  }
    64  func (sp *ScannerRPos) Bytes() []byte {
    65  	start, end := sp.StartEnd()
    66  	start -= sp.sc.R.Min()
    67  	end -= sp.sc.R.Min()
    68  	return sp.sc.Scanner.Src[start:end]
    69  }