package  decodemeta 
 
 
 
 
 
 
 
import  ( 
	"bufio"  
	"encoding/binary"  
	"fmt"  
	"hash/fnv"  
	"internal/coverage"  
	"internal/coverage/slicereader"  
	"internal/coverage/stringtab"  
	"io"  
	"os"  
) 
 
 
 
type  CoverageMetaFileReader  struct  { 
	f          *os .File  
	hdr        coverage .MetaFileHeader  
	tmp        []byte  
	pkgOffsets []uint64  
	pkgLengths []uint64  
	strtab     *stringtab .Reader  
	fileRdr    *bufio .Reader  
	fileView   []byte  
	debug      bool  
} 
 
 
 
 
 
 
 
func  NewCoverageMetaFileReader  (f  *os .File , fileView  []byte ) (*CoverageMetaFileReader , error ) { 
	r  := &CoverageMetaFileReader { 
		f :        f , 
		fileView : fileView , 
		tmp :      make ([]byte , 256 ), 
	} 
 
	if  err  := r .readFileHeader (); err  != nil  { 
		return  nil , err  
	} 
	return  r , nil  
} 
 
func  (r  *CoverageMetaFileReader ) readFileHeader () error  { 
	var  err  error  
 
	r .fileRdr  = bufio .NewReader (r .f ) 
 
	 
	if  err  := binary .Read (r .fileRdr , binary .LittleEndian , &r .hdr ); err  != nil  { 
		return  err  
	} 
 
	 
	m  := r .hdr .Magic  
	g  := coverage .CovMetaMagic  
	if  m [0 ] != g [0 ] || m [1 ] != g [1 ] || m [2 ] != g [2 ] || m [3 ] != g [3 ] { 
		return  fmt .Errorf ("invalid meta-data file magic string" ) 
	} 
 
	 
 
	if  r .hdr .Version  > coverage .MetaFileVersion  { 
		return  fmt .Errorf ("meta-data file withn unknown version %d (expected %d)" , r .hdr .Version , coverage .MetaFileVersion ) 
	} 
 
	 
	r .pkgOffsets  = make ([]uint64 , r .hdr .Entries ) 
	for  i  := uint64 (0 ); i  < r .hdr .Entries ; i ++ { 
		if  r .pkgOffsets [i ], err  = r .rdUint64 (); err  != nil  { 
			return  err  
		} 
		if  r .pkgOffsets [i ] > r .hdr .TotalLength  { 
			return  fmt .Errorf ("insane pkg offset %d: %d > totlen %d" , 
				i , r .pkgOffsets [i ], r .hdr .TotalLength ) 
		} 
	} 
	r .pkgLengths  = make ([]uint64 , r .hdr .Entries ) 
	for  i  := uint64 (0 ); i  < r .hdr .Entries ; i ++ { 
		if  r .pkgLengths [i ], err  = r .rdUint64 (); err  != nil  { 
			return  err  
		} 
		if  r .pkgLengths [i ] > r .hdr .TotalLength  { 
			return  fmt .Errorf ("insane pkg length %d: %d > totlen %d" , 
				i , r .pkgLengths [i ], r .hdr .TotalLength ) 
		} 
	} 
 
	 
	b  := make ([]byte , r .hdr .StrTabLength ) 
	nr , err  := r .fileRdr .Read (b ) 
	if  err  != nil  { 
		return  err  
	} 
	if  nr  != int (r .hdr .StrTabLength ) { 
		return  fmt .Errorf ("error: short read on string table" ) 
	} 
	slr  := slicereader .NewReader (b , false  ) 
	r .strtab  = stringtab .NewReader (slr ) 
	r .strtab .Read () 
 
	if  r .debug  { 
		fmt .Fprintf (os .Stderr , "=-= read-in header is: %+v\n" , *r ) 
	} 
 
	return  nil  
} 
 
func  (r  *CoverageMetaFileReader ) rdUint64 () (uint64 , error ) { 
	r .tmp  = r .tmp [:0 ] 
	r .tmp  = append (r .tmp , make ([]byte , 8 )...) 
	n , err  := r .fileRdr .Read (r .tmp ) 
	if  err  != nil  { 
		return  0 , err  
	} 
	if  n  != 8  { 
		return  0 , fmt .Errorf ("premature end of file on read" ) 
	} 
	v  := binary .LittleEndian .Uint64 (r .tmp ) 
	return  v , nil  
} 
 
 
 
func  (r  *CoverageMetaFileReader ) NumPackages () uint64  { 
	return  r .hdr .Entries  
} 
 
 
 
 
func  (r  *CoverageMetaFileReader ) CounterMode () coverage .CounterMode  { 
	return  r .hdr .CMode  
} 
 
 
 
 
func  (r  *CoverageMetaFileReader ) CounterGranularity () coverage .CounterGranularity  { 
	return  r .hdr .CGranularity  
} 
 
 
 
 
func  (r  *CoverageMetaFileReader ) FileHash () [16 ]byte  { 
	return  r .hdr .MetaFileHash  
} 
 
 
 
 
 
 
 
 
func  (r  *CoverageMetaFileReader ) GetPackageDecoder (pkIdx  uint32 , payloadbuf  []byte ) (*CoverageMetaDataDecoder , []byte , error ) { 
	pp , err  := r .GetPackagePayload (pkIdx , payloadbuf ) 
	if  r .debug  { 
		h  := fnv .New128a () 
		h .Write (pp ) 
		fmt .Fprintf (os .Stderr , "=-= pkidx=%d payload length is %d hash=%s\n" , 
			pkIdx , len (pp ), fmt .Sprintf ("%x" , h .Sum (nil ))) 
	} 
	if  err  != nil  { 
		return  nil , nil , err  
	} 
	mdd , err  := NewCoverageMetaDataDecoder (pp , r .fileView  != nil ) 
	if  err  != nil  { 
		return  nil , nil , err  
	} 
	return  mdd , pp , nil  
} 
 
 
 
 
 
 
 
 
func  (r  *CoverageMetaFileReader ) GetPackagePayload (pkIdx  uint32 , payloadbuf  []byte ) ([]byte , error ) { 
 
	 
	if  uint64 (pkIdx ) >= r .hdr .Entries  { 
		return  nil , fmt .Errorf ("GetPackagePayload: illegal pkg index %d" , pkIdx ) 
	} 
	off  := r .pkgOffsets [pkIdx ] 
	len  := r .pkgLengths [pkIdx ] 
 
	if  r .debug  { 
		fmt .Fprintf (os .Stderr , "=-= for pk %d, off=%d len=%d\n" , pkIdx , off , len ) 
	} 
 
	if  r .fileView  != nil  { 
		return  r .fileView [off  : off +len ], nil  
	} 
 
	payload  := payloadbuf [:0 ] 
	if  cap (payload ) < int (len ) { 
		payload  = make ([]byte , 0 , len ) 
	} 
	payload  = append (payload , make ([]byte , len )...) 
	if  _ , err  := r .f .Seek (int64 (off ), io .SeekStart ); err  != nil  { 
		return  nil , err  
	} 
	if  _ , err  := io .ReadFull (r .f , payload ); err  != nil  { 
		return  nil , err  
	} 
	return  payload , nil  
} 
  
The pages are generated with Golds   v0.7.9-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 .