You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tarzst.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package archiver
  2. import (
  3. "fmt"
  4. "io"
  5. "strings"
  6. "github.com/klauspost/compress/zstd"
  7. )
  8. // TarZstd facilitates Zstandard compression
  9. // (RFC 8478) of tarball archives.
  10. type TarZstd struct {
  11. *Tar
  12. }
  13. // CheckExt ensures the file extension matches the format.
  14. func (*TarZstd) CheckExt(filename string) error {
  15. if !strings.HasSuffix(filename, ".tar.zst") {
  16. return fmt.Errorf("filename must have a .tar.zst extension")
  17. }
  18. return nil
  19. }
  20. // Archive creates a compressed tar file at destination
  21. // containing the files listed in sources. The destination
  22. // must end with ".tar.zst" or ".tzst". File paths can be
  23. // those of regular files or directories; directories will
  24. // be recursively added.
  25. func (tzst *TarZstd) Archive(sources []string, destination string) error {
  26. err := tzst.CheckExt(destination)
  27. if err != nil {
  28. return fmt.Errorf("output %s", err.Error())
  29. }
  30. tzst.wrapWriter()
  31. return tzst.Tar.Archive(sources, destination)
  32. }
  33. // Unarchive unpacks the compressed tarball at
  34. // source to destination. Destination will be
  35. // treated as a folder name.
  36. func (tzst *TarZstd) Unarchive(source, destination string) error {
  37. tzst.wrapReader()
  38. return tzst.Tar.Unarchive(source, destination)
  39. }
  40. // Walk calls walkFn for each visited item in archive.
  41. func (tzst *TarZstd) Walk(archive string, walkFn WalkFunc) error {
  42. tzst.wrapReader()
  43. return tzst.Tar.Walk(archive, walkFn)
  44. }
  45. // Create opens txz for writing a compressed
  46. // tar archive to out.
  47. func (tzst *TarZstd) Create(out io.Writer) error {
  48. tzst.wrapWriter()
  49. return tzst.Tar.Create(out)
  50. }
  51. // Open opens t for reading a compressed archive from
  52. // in. The size parameter is not used.
  53. func (tzst *TarZstd) Open(in io.Reader, size int64) error {
  54. tzst.wrapReader()
  55. return tzst.Tar.Open(in, size)
  56. }
  57. // Extract extracts a single file from the tar archive.
  58. // If the target is a directory, the entire folder will
  59. // be extracted into destination.
  60. func (tzst *TarZstd) Extract(source, target, destination string) error {
  61. tzst.wrapReader()
  62. return tzst.Tar.Extract(source, target, destination)
  63. }
  64. func (tzst *TarZstd) wrapWriter() {
  65. var zstdw *zstd.Encoder
  66. tzst.Tar.writerWrapFn = func(w io.Writer) (io.Writer, error) {
  67. var err error
  68. zstdw, err = zstd.NewWriter(w)
  69. return zstdw, err
  70. }
  71. tzst.Tar.cleanupWrapFn = func() {
  72. zstdw.Close()
  73. }
  74. }
  75. func (tzst *TarZstd) wrapReader() {
  76. var zstdr *zstd.Decoder
  77. tzst.Tar.readerWrapFn = func(r io.Reader) (io.Reader, error) {
  78. var err error
  79. zstdr, err = zstd.NewReader(r)
  80. return zstdr, err
  81. }
  82. tzst.Tar.cleanupWrapFn = func() {
  83. zstdr.Close()
  84. }
  85. }
  86. func (tzst *TarZstd) String() string { return "tar.zst" }
  87. // NewTarZstd returns a new, default instance ready to be customized and used.
  88. func NewTarZstd() *TarZstd {
  89. return &TarZstd{
  90. Tar: NewTar(),
  91. }
  92. }
  93. // Compile-time checks to ensure type implements desired interfaces.
  94. var (
  95. _ = Reader(new(TarZstd))
  96. _ = Writer(new(TarZstd))
  97. _ = Archiver(new(TarZstd))
  98. _ = Unarchiver(new(TarZstd))
  99. _ = Walker(new(TarZstd))
  100. _ = ExtensionChecker(new(TarZstd))
  101. _ = Extractor(new(TarZstd))
  102. )
  103. // DefaultTarZstd is a convenient archiver ready to use.
  104. var DefaultTarZstd = NewTarZstd()