diff --git a/pkg/cmd/util.go b/pkg/cmd/util.go index 23854842f..0dafb2a99 100644 --- a/pkg/cmd/util.go +++ b/pkg/cmd/util.go @@ -174,7 +174,7 @@ func ReadTraceFile(filename string) lt.TraceFile { tracefile lt.TraceFile ) // Read data file - data, err := os.ReadFile(filename) + filename, data, err := file.ReadAndUncompress(filename) // Check success if err == nil { // Check file extension @@ -220,7 +220,7 @@ func ReadTraceFile(filename string) lt.TraceFile { func ReadBatchedTraceFile(filename string) []lt.TraceFile { var ( stats = util.NewPerfStats() - lines = file.ReadInputFile(filename) + lines = file.ReadInputFileAsLines(filename) traces = make([]lt.TraceFile, 0) ) // Read constraints line by line diff --git a/pkg/test/util/check_valid.go b/pkg/test/util/check_valid.go index 2d742341c..071f1be93 100644 --- a/pkg/test/util/check_valid.go +++ b/pkg/test/util/check_valid.go @@ -378,7 +378,7 @@ func (p *traceId) String() string { // ReadTracesFile reads a file containing zero or more traces expressed as JSON, where // each trace is on a separate line. func ReadTracesFile(filename string) []lt.TraceFile { - lines := file.ReadInputFile(filename) + lines := file.ReadInputFileAsLines(filename) traces := make([]lt.TraceFile, len(lines)) // Read constraints line by line for i, line := range lines { diff --git a/pkg/util/file/files.go b/pkg/util/file/files.go index 083104db8..d4a2b90dd 100644 --- a/pkg/util/file/files.go +++ b/pkg/util/file/files.go @@ -15,14 +15,59 @@ package file import ( "bufio" "compress/bzip2" + "compress/gzip" "errors" "io" "os" "path" + "strings" ) -// ReadInputFile reads an input file as a sequence of lines. -func ReadInputFile(filename string) []string { +// ReadAndUncompress reads a given file and, if its extension indicates it is +// compressed, then it decompresses it before returning the decompressed byte +// and the underlying filename (e.g. if original filename was "file.lt.gz" then +// it returns "file.lt"). Supported compression formats are "bz2" and "gz". +func ReadAndUncompress(filename string) (string, []byte, error) { + var ( + ext = path.Ext(filename) + reader io.Reader + err error + data []byte + ) + // Open file for reading + file, err := os.Open(filename) + // Sanity check for error + if err != nil { + return filename, nil, err + } + // Setup file close behaviour + defer func() { + if err := file.Close(); err != nil { + panic(err) + } + }() + // + reader = file + // check extension + switch ext { + case ".bz2": + reader = bzip2.NewReader(reader) + filename = strings.TrimSuffix(filename, ext) + case ".gz": + if reader, err = gzip.NewReader(reader); err != nil { + return filename, nil, err + } + // + filename = strings.TrimSuffix(filename, ext) + } + // + data, err = io.ReadAll(reader) + // + return filename, data, err +} + +// ReadInputFileAsLines reads an input file as a sequence of lines. +func ReadInputFileAsLines(filename string) []string { file, err := os.Open(filename) // Check whether file exists if errors.Is(err, os.ErrNotExist) {