Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/vertoforce/streamregex

go 1.12
go 1.24
2 changes: 1 addition & 1 deletion streamregexdoc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ func ExampleFindReaderIndex() {
fmt.Println(match, index)
}

// Output: stream of
// Output: stream of [20 32]
}
13 changes: 10 additions & 3 deletions steamregexindex.go → streamregexindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,23 @@ func SplitRegexIndex(re *regexp.Regexp, maxMatchLength int, indexChannel chan []
}
}

// FindReaderIndex returns a channel of matched []byte from the reader and a channel of the locations at wich the matches where found
// This function will allocate maxMatchLength*2 bytes of memory
// FindReaderIndex returns a channel of matched strings from the reader and a channel of the locations
// ([start, end] byte offsets) at which the matches were found.
// This function will allocate maxMatchLength*2 bytes of memory.
//
// Both channels are closed once scanning finishes. The caller MUST drain both channels
// (read every match and its corresponding index); each match sends its index before the
// match itself, so reading matches without also reading indexes will deadlock the scanner.
// Canceling ctx stops scanning after the current match.
func FindReaderIndex(ctx context.Context, r *regexp.Regexp, maxMatchLength int, reader io.Reader) (chan string, chan []int) {
allMatches := make(chan string)
allIndexes := make(chan []int, 1) // Avoid deadlock because if location is not read it blocks SplitRegexIndex from returning the match
allIndexes := make(chan []int, 1) // Buffered so SplitRegexIndex can send the index and still return the match before the consumer reads the index

buf := make([]byte, maxMatchLength*2)

go func() {
defer close(allMatches)
defer close(allIndexes)

scanner := bufio.NewScanner(reader)
scanner.Buffer(buf, maxMatchLength)
Expand Down
File renamed without changes.