go-hep.org/x/hep@v0.38.1/rio/cmd/rio-ls-records/main.go (about)

     1  // Copyright ©2017 The go-hep 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  // rio-ls-records displays the list of records stored in a given rio file.
     6  package main
     7  
     8  import (
     9  	"flag"
    10  	"fmt"
    11  	"log"
    12  	"os"
    13  
    14  	"go-hep.org/x/hep/rio"
    15  )
    16  
    17  func main() {
    18  
    19  	log.SetFlags(0)
    20  	log.SetPrefix("rio-ls-records: ")
    21  
    22  	flag.Usage = func() {
    23  		fmt.Fprintf(os.Stderr, `Usage: rio-ls-records [options] <file.rio> [<file2.rio> [<file3.rio> [...]]]
    24  	
    25  ex:
    26   $ rio-ls-records file.rio
    27   `,
    28  		)
    29  	}
    30  
    31  	flag.Parse()
    32  
    33  	if flag.NArg() < 1 {
    34  		log.Printf("missing filename argument\n")
    35  		flag.Usage()
    36  		flag.PrintDefaults()
    37  		os.Exit(1)
    38  	}
    39  
    40  	for _, fname := range flag.Args() {
    41  		inspect(fname)
    42  	}
    43  }
    44  
    45  func inspect(fname string) {
    46  	log.Printf("inspecting file [%s]...\n", fname)
    47  	if fname == "" {
    48  		flag.Usage()
    49  		flag.PrintDefaults()
    50  		os.Exit(1)
    51  	}
    52  
    53  	rtypes := metaData(fname)
    54  
    55  	f, err := os.Open(fname)
    56  	if err != nil {
    57  		log.Fatal(err)
    58  	}
    59  	defer f.Close()
    60  
    61  	r, err := rio.NewReader(f)
    62  	if err != nil {
    63  		log.Fatalf("error creating rio.Reader: %v\n", err)
    64  	}
    65  
    66  	scan := rio.NewScanner(r)
    67  	for scan.Scan() {
    68  		// scans through the whole stream
    69  		err = scan.Err()
    70  		if err != nil {
    71  			break
    72  		}
    73  		rec := scan.Record()
    74  		if rec.Name() == rio.MetaRecord {
    75  			continue
    76  		}
    77  		rtype := rtypes[rec.Name()]
    78  		if rtype != "" {
    79  			rtype = "type=" + rtype
    80  		}
    81  		fmt.Printf(" -> %-20s%s\n", rec.Name(), rtype)
    82  	}
    83  	err = scan.Err()
    84  	if err != nil {
    85  		log.Fatalf("error during file scan: %v\n", err)
    86  	}
    87  
    88  	log.Printf("inspecting file [%s]... [done]\n", fname)
    89  }
    90  
    91  func metaData(fname string) map[string]string {
    92  	f, err := os.Open(fname)
    93  	if err != nil {
    94  		log.Fatal(err)
    95  	}
    96  	defer f.Close()
    97  
    98  	var rtypes = make(map[string]string)
    99  	r, err := rio.NewReader(f)
   100  	if err != nil {
   101  		return rtypes
   102  	}
   103  
   104  	scan := rio.NewScanner(r)
   105  	scan.Select([]rio.Selector{{Name: rio.MetaRecord, Unpack: true}})
   106  	if !scan.Scan() {
   107  		log.Fatal(scan.Err())
   108  	}
   109  	rec := scan.Record()
   110  	if rec == nil {
   111  		return rtypes
   112  	}
   113  
   114  	blk := rec.Block(rio.MetaRecord)
   115  	if blk == nil {
   116  		return rtypes
   117  	}
   118  
   119  	var meta rio.Metadata
   120  	err = blk.Read(&meta)
   121  	if err != nil {
   122  		return rtypes
   123  	}
   124  
   125  	for _, mrec := range meta.Records {
   126  		mblk := mrec.Blocks[0]
   127  		rtypes[mblk.Name] = mblk.Type
   128  	}
   129  
   130  	return rtypes
   131  }