Skip to content

Consider exposing functionality to retrieve the size of compressed streams #444

Description

@burnedskies

Currently there's no way to get the compressed size of a packed stream, and for some use cases it can be useful.

Here is an example.

package main

import (
	"fmt"

	"github.com/bodgit/sevenzip"
)

func main() {
	o("testdata/t0.7z")
	o("testdata/t4.7z")
}

func o(name string) {
	r, err := sevenzip.OpenReader(name)
	if err != nil {
		panic(err)
	}

	fmt.Println("Archive contents for:", name)
	for _, file := range r.File {
		stream, err := r.PackedStreamSize(file.Stream)
		if err != nil {
			panic(err)
		}

		fmt.Printf(
			"%-20s | Checksum: %08X | Stream: %02d | Uncompressed Size: %-9d | Compressed Stream Size: %d\n",
			file.Name,
			file.CRC32,
			file.Stream,
			file.UncompressedSize,
			stream,
		)
	}

}

Expected output

Archive contents for: testdata/t0.7z
bar                  | Checksum: 04A2B3E9 | Stream: 00 | Uncompressed Size: 4         | Compressed Stream Size: 4
foo                  | Checksum: 7E3265A8 | Stream: 01 | Uncompressed Size: 4         | Compressed Stream Size: 4
Archive contents for: testdata/t4.7z
bar                  | Checksum: 04A2B3E9 | Stream: 00 | Uncompressed Size: 4         | Compressed Stream Size: 16
foo                  | Checksum: 7E3265A8 | Stream: 00 | Uncompressed Size: 4         | Compressed Stream Size: 16

Here is a patch for reference.

diff --git a/reader.go b/reader.go
index 8ff32ef..ca42fbe 100644
--- a/reader.go
+++ b/reader.go
@@ -801,6 +801,14 @@ func (z *Reader) openReadDir(dir string) []fileListEntry {
 	return files[i:j]
 }
 
+func (z *Reader) PackedStreamSize(stream int) (uint64, error) {
+	if 0 <= stream && len(z.si.packInfo.size) >= stream {
+		return z.si.packInfo.size[stream], nil
+	}
+
+	return 0, fmt.Errorf("stream `%d` is out of range", stream)
+}
+
 type openDir struct {
 	e      *fileListEntry
 	files  []fileListEntry

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions