forked from
tangled.org/core
Monorepo for Tangled — https://tangled.org
1package knotserver
2
3import (
4 "bytes"
5 "io"
6 "log/slog"
7 "net/http"
8 "strings"
9
10 "tangled.sh/tangled.sh/core/types"
11)
12
13func countLines(r io.Reader) (int, error) {
14 buf := make([]byte, 32*1024)
15 bufLen := 0
16 count := 0
17 nl := []byte{'\n'}
18
19 for {
20 c, err := r.Read(buf)
21 if c > 0 {
22 bufLen += c
23 }
24 count += bytes.Count(buf[:c], nl)
25
26 switch {
27 case err == io.EOF:
28 /* handle last line not having a newline at the end */
29 if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' {
30 count++
31 }
32 return count, nil
33 case err != nil:
34 return 0, err
35 }
36 }
37}
38
39func (h *Handle) showFile(resp types.RepoBlobResponse, w http.ResponseWriter, l *slog.Logger) {
40 lc, err := countLines(strings.NewReader(resp.Contents))
41 if err != nil {
42 // Non-fatal, we'll just skip showing line numbers in the template.
43 l.Warn("counting lines", "error", err)
44 }
45
46 resp.Lines = lc
47 writeJSON(w, resp)
48}