package sevenzip import ( "errors" "io" "sync" "bookhoard/internal/sevenzip/internal/aes7z" "bookhoard/internal/sevenzip/internal/bcj2" "bookhoard/internal/sevenzip/internal/bra" "bookhoard/internal/sevenzip/internal/brotli" "bookhoard/internal/sevenzip/internal/bzip2" "bookhoard/internal/sevenzip/internal/deflate" "bookhoard/internal/sevenzip/internal/delta" "bookhoard/internal/sevenzip/internal/lz4" "bookhoard/internal/sevenzip/internal/lzma" "bookhoard/internal/sevenzip/internal/lzma2" "bookhoard/internal/sevenzip/internal/zstd" ) // Decompressor describes the function signature that decompression/decryption // methods must implement to return a new instance of themselves. They are // passed any property bytes, the size of the stream and a slice of at least // one io.ReadCloser's providing the stream(s) of bytes. type Decompressor func([]byte, uint64, []io.ReadCloser) (io.ReadCloser, error) var ( //nolint:gochecknoglobals decompressors sync.Map errNeedOneReader = errors.New("copy: need exactly one reader") ) func newCopyReader(_ []byte, _ uint64, readers []io.ReadCloser) (io.ReadCloser, error) { if len(readers) != 1 { return nil, errNeedOneReader } // just return the passed io.ReadCloser) return readers[0], nil } //nolint:gochecknoinits func init() { // Copy RegisterDecompressor([]byte{0x00}, newCopyReader) // Delta RegisterDecompressor([]byte{0x03}, delta.NewReader) // LZMA RegisterDecompressor([]byte{0x03, 0x01, 0x01}, lzma.NewReader) // BCJ RegisterDecompressor([]byte{0x03, 0x03, 0x01, 0x03}, bra.NewBCJReader) // BCJ2 RegisterDecompressor([]byte{0x03, 0x03, 0x01, 0x1b}, bcj2.NewReader) // PPC RegisterDecompressor([]byte{0x03, 0x03, 0x02, 0x05}, bra.NewPPCReader) // ARM RegisterDecompressor([]byte{0x03, 0x03, 0x05, 0x01}, bra.NewARMReader) // SPARC RegisterDecompressor([]byte{0x03, 0x03, 0x08, 0x05}, bra.NewSPARCReader) // Deflate RegisterDecompressor([]byte{0x04, 0x01, 0x08}, deflate.NewReader) // Bzip2 RegisterDecompressor([]byte{0x04, 0x02, 0x02}, bzip2.NewReader) // Zstandard RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x01}, zstd.NewReader) // Brotli RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x02}, brotli.NewReader) // LZ4 RegisterDecompressor([]byte{0x04, 0xf7, 0x11, 0x04}, lz4.NewReader) // AES-CBC-256 & SHA-256 RegisterDecompressor([]byte{0x06, 0xf1, 0x07, 0x01}, aes7z.NewReader) // LZMA2 RegisterDecompressor([]byte{0x21}, lzma2.NewReader) } // RegisterDecompressor allows custom decompressors for a specified method ID. func RegisterDecompressor(method []byte, dcomp Decompressor) { decompressors.Store(string(method), dcomp) } func decompressor(method []byte) Decompressor { di, ok := decompressors.Load(string(method)) if !ok { return nil } if d, ok := di.(Decompressor); ok { return d } return nil }