69 lines
1.2 KiB
Go
69 lines
1.2 KiB
Go
|
package zipread
|
||
|
|
||
|
import (
|
||
|
"archive/zip"
|
||
|
"bytes"
|
||
|
"io"
|
||
|
"io/fs"
|
||
|
"os"
|
||
|
)
|
||
|
|
||
|
type SizedReaderAt struct {
|
||
|
R io.ReaderAt
|
||
|
Size int64
|
||
|
}
|
||
|
|
||
|
func NewSizedReaderFromOsFile(f *os.File) (*SizedReaderAt, error) {
|
||
|
stat, err := f.Stat()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &SizedReaderAt{R: f, Size: stat.Size()}, nil
|
||
|
}
|
||
|
|
||
|
func NewSizedReaderFromReader(r io.Reader) (*SizedReaderAt, error) {
|
||
|
data, err := io.ReadAll(r)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
contents := bytes.NewReader(data)
|
||
|
return &SizedReaderAt{R: contents, Size: int64(len(data))}, nil
|
||
|
}
|
||
|
|
||
|
type ZipRead struct {
|
||
|
*zip.Reader
|
||
|
}
|
||
|
|
||
|
func New(r *SizedReaderAt) (*ZipRead, error) {
|
||
|
zr, err := zip.NewReader(r.R, r.Size)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &ZipRead{zr}, nil
|
||
|
}
|
||
|
|
||
|
func FromOsFile(f *os.File) (*ZipRead, error) {
|
||
|
r, err := NewSizedReaderFromOsFile(f)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return New(r)
|
||
|
}
|
||
|
|
||
|
func FromFsFile(f fs.File) (*ZipRead, error) {
|
||
|
r, err := NewSizedReaderFromReader(f)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return New(r)
|
||
|
}
|
||
|
|
||
|
func (zr *ZipRead) OpenZip(path string) (*ZipRead, error) {
|
||
|
f, err := zr.Reader.Open(path)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
return FromFsFile(f)
|
||
|
}
|