1package main 2 3import ( 4 "flag" 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 10 "github.com/linkedin/goavro/v2" 11) 12 13var ( 14 showCount = flag.Bool("count", false, "show count of data items") 15 showSchema = flag.Bool("schema", false, "show data schema") 16) 17 18func usage() { 19 executable, err := os.Executable() 20 if err != nil { 21 executable = os.Args[0] 22 } 23 base := filepath.Base(executable) 24 fmt.Fprintf(os.Stderr, "Usage of %s:\n", base) 25 fmt.Fprintf(os.Stderr, "\t%s [-count] [-schema] [file1.avro...]\n", base) 26 fmt.Fprintf(os.Stderr, "\tAs a special case, when there are no filename arguments, %s will read\n", base) 27 fmt.Fprintf(os.Stderr, "\tfrom its standard input.\n") 28 flag.PrintDefaults() 29 os.Exit(2) 30} 31 32func main() { 33 flag.Parse() 34 35 args := flag.Args() 36 37 if len(args) == 0 { 38 stat, err := os.Stdin.Stat() 39 if err != nil { 40 bail(err) 41 } 42 if (stat.Mode() & os.ModeCharDevice) != 0 { 43 usage() 44 } 45 if err := headerFromReader(os.Stdin, ""); err != nil { 46 bail(err) 47 } 48 } 49 50 for _, arg := range args { 51 fh, err := os.Open(arg) 52 if err != nil { 53 bail(err) 54 } 55 if len(args) > 1 { 56 arg += ": " 57 } else { 58 arg = "" 59 } 60 if err := headerFromReader(fh, arg); err != nil { 61 bail(err) 62 } 63 if err := fh.Close(); err != nil { 64 bail(err) 65 } 66 } 67} 68 69func headerFromReader(ior io.Reader, prefix string) error { 70 ocfr, err := goavro.NewOCFReader(ior) 71 if err != nil { 72 return err 73 } 74 75 fmt.Printf("%sCompression Algorithm (avro.codec): %q\n", prefix, ocfr.CompressionName()) 76 77 if *showSchema { 78 fmt.Printf("%sSchema (avro.schema):\n%s\n", prefix, ocfr.Codec().Schema()) 79 } 80 81 if !*showCount { 82 return nil 83 } 84 85 var decoded, errors int 86 87 for ocfr.Scan() { 88 _, err := ocfr.Read() 89 if err != nil { 90 fmt.Fprintf(os.Stderr, "%s\n", err) 91 errors++ 92 continue 93 } 94 decoded++ 95 } 96 97 if decoded > 0 { 98 fmt.Printf("%sSuccessfully decoded: %d\n", prefix, decoded) 99 } 100 if errors > 0 { 101 fmt.Printf("%sCannot decode: %d\n", prefix, errors) 102 } 103 104 return ocfr.Err() 105} 106 107func bail(err error) { 108 fmt.Fprintf(os.Stderr, "%s\n", err) 109 os.Exit(1) 110} 111