1
2
3
4
5 package cov
6
7 import (
8 "cmd/internal/bio"
9 "io"
10 "os"
11 )
12
13
14
15
16
17
18
19 type MReader struct {
20 f *os.File
21 rdr *bio.Reader
22 fileView []byte
23 off int64
24 }
25
26 func NewMreader(f *os.File) (*MReader, error) {
27 rdr := bio.NewReader(f)
28 fi, err := f.Stat()
29 if err != nil {
30 return nil, err
31 }
32 r := MReader{
33 f: f,
34 rdr: rdr,
35 fileView: rdr.SliceRO(uint64(fi.Size())),
36 }
37 return &r, nil
38 }
39
40 func (r *MReader) Read(p []byte) (int, error) {
41 if r.fileView != nil {
42 amt := len(p)
43 toread := r.fileView[r.off:]
44 if len(toread) < 1 {
45 return 0, io.EOF
46 }
47 if len(toread) < amt {
48 amt = len(toread)
49 }
50 copy(p, toread)
51 r.off += int64(amt)
52 return amt, nil
53 }
54 return io.ReadFull(r.rdr, p)
55 }
56
57 func (r *MReader) ReadByte() (byte, error) {
58 if r.fileView != nil {
59 toread := r.fileView[r.off:]
60 if len(toread) < 1 {
61 return 0, io.EOF
62 }
63 rv := toread[0]
64 r.off++
65 return rv, nil
66 }
67 return r.rdr.ReadByte()
68 }
69
70 func (r *MReader) Seek(offset int64, whence int) (int64, error) {
71 if r.fileView == nil {
72 return r.rdr.MustSeek(offset, whence), nil
73 }
74 switch whence {
75 case io.SeekStart:
76 r.off = offset
77 return offset, nil
78 case io.SeekCurrent:
79 return r.off, nil
80 case io.SeekEnd:
81 r.off = int64(len(r.fileView)) + offset
82 return r.off, nil
83 }
84 panic("other modes not implemented")
85 }
86
View as plain text