github.com/bir3/gocompiler@v0.9.2202/src/cmd/internal/cov/mreader.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cov 6 7 import ( 8 "github.com/bir3/gocompiler/src/cmd/internal/bio" 9 "io" 10 "os" 11 ) 12 13 // This file contains the helper "MReader", a wrapper around bio plus 14 // an "mmap'd read-only" view of the file obtained from bio.SliceRO(). 15 // MReader is designed to implement the io.ReaderSeeker interface. 16 // Since bio.SliceOS() is not guaranteed to succeed, MReader falls back 17 // on explicit reads + seeks provided by bio.Reader if needed. 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 }