package decodemeta
import (
"encoding/binary"
"fmt"
"internal/coverage"
"internal/coverage/slicereader"
"internal/coverage/stringtab"
"io"
"os"
)
type CoverageMetaDataDecoder struct {
r *slicereader .Reader
hdr coverage .MetaSymbolHeader
strtab *stringtab .Reader
tmp []byte
debug bool
}
func NewCoverageMetaDataDecoder (b []byte , readonly bool ) (*CoverageMetaDataDecoder , error ) {
slr := slicereader .NewReader (b , readonly )
x := &CoverageMetaDataDecoder {
r : slr ,
tmp : make ([]byte , 0 , 256 ),
}
if err := x .readHeader (); err != nil {
return nil , err
}
if err := x .readStringTable (); err != nil {
return nil , err
}
return x , nil
}
func (d *CoverageMetaDataDecoder ) readHeader () error {
if err := binary .Read (d .r , binary .LittleEndian , &d .hdr ); err != nil {
return err
}
if d .debug {
fmt .Fprintf (os .Stderr , "=-= after readHeader: %+v\n" , d .hdr )
}
return nil
}
func (d *CoverageMetaDataDecoder ) readStringTable () error {
stringTableLocation := int64 (coverage .CovMetaHeaderSize + 4 *d .hdr .NumFuncs )
if _ , err := d .r .Seek (stringTableLocation , io .SeekStart ); err != nil {
return err
}
d .strtab = stringtab .NewReader (d .r )
d .strtab .Read ()
return nil
}
func (d *CoverageMetaDataDecoder ) PackagePath () string {
return d .strtab .Get (d .hdr .PkgPath )
}
func (d *CoverageMetaDataDecoder ) PackageName () string {
return d .strtab .Get (d .hdr .PkgName )
}
func (d *CoverageMetaDataDecoder ) ModulePath () string {
return d .strtab .Get (d .hdr .ModulePath )
}
func (d *CoverageMetaDataDecoder ) NumFuncs () uint32 {
return d .hdr .NumFuncs
}
func (d *CoverageMetaDataDecoder ) ReadFunc (fidx uint32 , f *coverage .FuncDesc ) error {
if fidx >= d .hdr .NumFuncs {
return fmt .Errorf ("illegal function index" )
}
funcOffsetLocation := int64 (coverage .CovMetaHeaderSize + 4 *fidx )
if _ , err := d .r .Seek (funcOffsetLocation , io .SeekStart ); err != nil {
return err
}
foff := d .r .ReadUint32 ()
if foff < uint32 (funcOffsetLocation ) || foff > d .hdr .Length {
return fmt .Errorf ("malformed func offset %d" , foff )
}
floc := int64 (foff )
if _ , err := d .r .Seek (floc , io .SeekStart ); err != nil {
return err
}
numUnits := uint32 (d .r .ReadULEB128 ())
fnameidx := uint32 (d .r .ReadULEB128 ())
fileidx := uint32 (d .r .ReadULEB128 ())
f .Srcfile = d .strtab .Get (fileidx )
f .Funcname = d .strtab .Get (fnameidx )
f .Units = f .Units [:0 ]
if cap (f .Units ) < int (numUnits ) {
f .Units = make ([]coverage .CoverableUnit , 0 , numUnits )
}
for k := uint32 (0 ); k < numUnits ; k ++ {
f .Units = append (f .Units ,
coverage .CoverableUnit {
StLine : uint32 (d .r .ReadULEB128 ()),
StCol : uint32 (d .r .ReadULEB128 ()),
EnLine : uint32 (d .r .ReadULEB128 ()),
EnCol : uint32 (d .r .ReadULEB128 ()),
NxStmts : uint32 (d .r .ReadULEB128 ()),
})
}
lit := d .r .ReadULEB128 ()
f .Lit = lit != 0
return nil
}
The pages are generated with Golds v0.7.0-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .