lsgo/third_party/lz4/cmd/lz4c/compress.go
lordwelch f56ee42b79 Change signatures to constant strings
Fix issues from golangci-lint

Add sublime project file
2021-01-11 01:24:36 -08:00

124 lines
3.0 KiB
Go

package main
import (
"flag"
"fmt"
"io"
"os"
"sync/atomic"
"code.cloudfoundry.org/bytefmt"
"github.com/schollz/progressbar/v3"
"github.com/pierrec/cmdflag"
"github.com/pierrec/lz4/v4"
)
// Compress compresses a set of files or from stdin to stdout.
func Compress(fs *flag.FlagSet) cmdflag.Handler {
var blockMaxSize string
fs.StringVar(&blockMaxSize, "size", "4M", "block max size [64K,256K,1M,4M]")
var blockChecksum bool
fs.BoolVar(&blockChecksum, "bc", false, "enable block checksum")
var streamChecksum bool
fs.BoolVar(&streamChecksum, "sc", false, "disable stream checksum")
var level int
fs.IntVar(&level, "l", 0, "compression level (0=fastest)")
var concurrency int
fs.IntVar(&concurrency, "c", -1, "concurrency (default=all CPUs")
return func(args ...string) (int, error) {
sz, err := bytefmt.ToBytes(blockMaxSize)
if err != nil {
return 0, err
}
zw := lz4.NewWriter(nil)
options := []lz4.Option{
lz4.BlockChecksumOption(blockChecksum),
lz4.BlockSizeOption(lz4.BlockSize(sz)),
lz4.ChecksumOption(streamChecksum),
lz4.CompressionLevelOption(lz4.CompressionLevel(level)),
lz4.ConcurrencyOption(concurrency),
}
if err := zw.Apply(options...); err != nil {
return 0, err
}
// Use stdin/stdout if no file provided.
if len(args) == 0 {
zw.Reset(os.Stdout)
_, err := io.Copy(zw, os.Stdin)
if err != nil {
return 0, err
}
return 0, zw.Close()
}
for fidx, filename := range args {
// Input file.
file, err := os.Open(filename)
if err != nil {
return fidx, err
}
finfo, err := file.Stat()
if err != nil {
return fidx, err
}
mode := finfo.Mode() // use the same mode for the output file
// Accumulate compressed bytes num.
var (
zsize int64
size = finfo.Size()
)
if size > 0 {
// Progress bar setup.
numBlocks := int(size) / int(sz)
bar := progressbar.NewOptions(numBlocks,
// File transfers are usually slow, make sure we display the bar at 0%.
progressbar.OptionSetRenderBlankState(true),
// Display the filename.
progressbar.OptionSetDescription(filename),
progressbar.OptionClearOnFinish(),
)
err = zw.Apply(
lz4.OnBlockDoneOption(func(n int) {
_ = bar.Add(1)
atomic.AddInt64(&zsize, int64(n))
}),
)
if err != nil {
return 0, err
}
}
// Output file.
zfilename := fmt.Sprintf("%s%s", filename, lz4Extension)
zfile, err := os.OpenFile(zfilename, os.O_CREATE|os.O_WRONLY, mode)
if err != nil {
return fidx, err
}
zw.Reset(zfile)
// Compress.
_, err = io.Copy(zw, file)
if err != nil {
return fidx, err
}
for _, c := range []io.Closer{zw, zfile} {
err := c.Close()
if err != nil {
return fidx, err
}
}
if size > 0 {
fmt.Printf("%s %.02f%%\n", zfilename, float64(zsize)*100/float64(size))
}
}
return len(args), nil
}
}