File: io.go

package info (click to toggle)
pat 0.19.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,296 kB
  • sloc: javascript: 3,891; sh: 124; makefile: 11
file content (48 lines) | stat: -rw-r--r-- 986 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package forms

import (
	"bufio"
	"bytes"
	"io"
	"log"
	"os"
	"sync"
	"unicode/utf8"
)

func readFile(path string) (string, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return "", err
	}
	// skipping over UTF-8 byte-ordering mark EFBBEF, some 3rd party templates use it
	// (e.g. Sonoma county's ICS213_v2.1_SonomaACS_TwoWay_Initial_Viewer.html)
	data = trimBom(data)
	if !utf8.Valid(data) {
		log.Printf("Warning: unsupported string encoding in file %q, expected UTF-8", path)
	}
	return string(data), nil
}

func trimBom(p []byte) []byte {
	return bytes.TrimLeftFunc(p, func(r rune) bool { return r == '\uFEFF' })
}

type trimBomReader struct {
	r    *bufio.Reader
	once sync.Once
}

func (r *trimBomReader) Read(p []byte) (int, error) {
	r.once.Do(func() {
		peek, _ := r.r.Peek(3)
		if bytes.ContainsRune(peek, '\uFEFF') {
			r.r.Discard(3)
		}
	})
	return r.r.Read(p)
}

func newTrimBomReader(r io.Reader) io.Reader {
	return &trimBomReader{r: bufio.NewReader(r)}
}