searchFile searches a single file for a regular expression. It limits the search to the first [maxFileSize] bytes of the file to avoid consuming too much memory.
(fsys fs.FS, path string, re *regexp.Regexp)
| 36 | // search to the first [maxFileSize] bytes of the file to avoid consuming too |
| 37 | // much memory. |
| 38 | func searchFile(fsys fs.FS, path string, re *regexp.Regexp) ([]fileSlice, error) { |
| 39 | f, err := fsys.Open(path) |
| 40 | if err != nil { |
| 41 | return nil, err |
| 42 | } |
| 43 | defer f.Close() |
| 44 | |
| 45 | r := &io.LimitedReader{R: f, N: maxFileSize} |
| 46 | data, err := io.ReadAll(r) |
| 47 | if err != nil { |
| 48 | return nil, err |
| 49 | } |
| 50 | |
| 51 | locs := re.FindAllIndex(data, -1) |
| 52 | if len(locs) == 0 { |
| 53 | return nil, nil |
| 54 | } |
| 55 | |
| 56 | matches := make([]fileSlice, len(locs)) |
| 57 | for i := range locs { |
| 58 | start, end := locs[i][0], locs[i][1] |
| 59 | matches[i] = fileSlice{ |
| 60 | path: path, |
| 61 | data: data[start:end], |
| 62 | offset: int64(start), |
| 63 | } |
| 64 | } |
| 65 | return matches, nil |
| 66 | } |
| 67 | |
| 68 | var envValues = sync.OnceValue(func() []string { |
| 69 | env := os.Environ() |