59 lines
1.1 KiB
Go
59 lines
1.1 KiB
Go
package detector
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
type (
|
|
Detector struct {
|
|
io.Reader
|
|
err error
|
|
data []byte
|
|
detectFunc func([]byte) string
|
|
}
|
|
errReader struct {
|
|
data []byte
|
|
err error
|
|
offset int
|
|
}
|
|
)
|
|
|
|
const contentTypeDetectSize = 512
|
|
|
|
func newReader(data []byte, err error) *errReader {
|
|
return &errReader{data: data, err: err}
|
|
}
|
|
|
|
func (r *errReader) Read(b []byte) (int, error) {
|
|
if r.offset >= len(r.data) {
|
|
return 0, io.EOF
|
|
}
|
|
n := copy(b, r.data[r.offset:])
|
|
r.offset += n
|
|
if r.offset >= len(r.data) {
|
|
return n, r.err
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func NewDetector(reader io.Reader, detectFunc func([]byte) string) *Detector {
|
|
return &Detector{
|
|
data: make([]byte, contentTypeDetectSize),
|
|
Reader: reader,
|
|
detectFunc: detectFunc,
|
|
}
|
|
}
|
|
|
|
func (d *Detector) Detect() (string, error) {
|
|
n, err := d.Reader.Read(d.data)
|
|
if err != nil && err != io.EOF {
|
|
d.err = err
|
|
return "", err
|
|
}
|
|
d.data = d.data[:n]
|
|
return d.detectFunc(d.data), nil
|
|
}
|
|
|
|
func (d *Detector) RestoredReader() io.Reader {
|
|
return io.MultiReader(newReader(d.data, d.err), d.Reader)
|
|
}
|