...
1package utils
2
3import (
4 "slices"
5 "strings"
6 "sync"
7)
8
9type PositionFinder interface {
10 // advance position to line after pattern found. return true if found
11 FindLineContaining(s string) bool
12 // insert line at position
13 AddLine(s string)
14 // return current content
15 Content() []byte
16}
17type positionFinder struct {
18 sync.Mutex
19 lines []string
20 line_pos int // only advances forward, points to the next line
21}
22
23/*
24a position finder helps finding certain positions in pieces of text. for example: find the '}' after the first occurence of line "foo" and "bar". Each call advances the position further. AddLine inserts a new line at current position.
25*/
26func NewPositionFinder(ct []byte) PositionFinder {
27 lines := strings.Split(string(ct), "\n")
28 res := &positionFinder{lines: lines}
29 return res
30}
31func (pf *positionFinder) remaining_lines() []string {
32 if pf.line_pos >= len(pf.lines) {
33 return nil
34 }
35 return pf.lines[pf.line_pos+1:]
36}
37
38// advance to position after a line containing...
39func (pf *positionFinder) FindLineContaining(s string) bool {
40 pf.Lock()
41 defer pf.Unlock()
42 for i, l := range pf.remaining_lines() {
43 // fmt.Printf("Line %d: \"%s\"\n", i, l)
44 if strings.Contains(l, s) {
45 pf.line_pos = pf.line_pos + i + 1
46 return true
47 }
48 }
49 return false
50}
51func (pf *positionFinder) AddLine(line string) {
52 pf.Lock()
53 defer pf.Unlock()
54 pos := pf.line_pos + 1
55 pf.lines = slices.Insert(pf.lines, pos, line)
56
57}
58func (pf *positionFinder) Content() []byte {
59 s := strings.Join(pf.lines, "\n")
60 return []byte(s)
61}
View as plain text