Skip to content

Instantly share code, notes, and snippets.

@richardlehane
Last active August 30, 2018 05:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richardlehane/ebaf088976e12c0444680b5436397be2 to your computer and use it in GitHub Desktop.
Save richardlehane/ebaf088976e12c0444680b5436397be2 to your computer and use it in GitHub Desktop.
example use of decompress package
package main
import (
"fmt"
"io"
"os"
"os/user"
"path/filepath"
"github.com/richardlehane/siegfried"
"github.com/richardlehane/siegfried/pkg/decompress"
)
func ReadMember(path, member string, fn func(io.Reader) error) error {
// load a siegfried signature file
usr, err := user.Current()
if err != nil {
return err
}
sf, err := siegfried.Load(filepath.Join(usr.HomeDir, "siegfried", "default.sig"))
if err != nil {
return err
}
// define idRdr func to recurse on nested contents within compressed files
var idRdr func(rdr io.Reader, name, mime string, sz int64) error
idRdr = func(rdr io.Reader, name, mime string, sz int64) error {
buf, err := sf.Buffer(rdr) // get a siegfried buffer. Buffers allows us to create multiple indpendent readers from a single source
defer sf.Put(buf) // return the buffer to siegfried's pool of buffers when done
if err != nil {
return err
}
if name == member { // call the passed function here if the name matches
err = fn(buf.Reader()) // new Reader() method gets a reader off a buffer
if err != nil {
return err
}
}
ids, err := sf.IdentifyBuffer(buf, nil, name, mime) // can of course use these sf IDs for other stuff here
if err != nil {
return err
}
arc := decompress.IsArc(ids)
if arc > 0 {
dec, err := decompress.New(arc, buf, name, sz)
if err != nil {
return err
}
for err = dec.Next(); err == nil; err = dec.Next() {
err = idRdr(dec.Reader(), dec.Path(), dec.MIME(), dec.Size()) // recurse on the contents of the archive
if err != nil {
return err
}
}
return err
}
return nil
}
info, err := os.Stat(path)
if err != nil {
return err
}
f, err := os.Open(path)
defer f.Close()
if err != nil {
return err
}
return idRdr(f, path, "", info.Size())
}
func main() {
fn := func(rdr io.Reader) error {
buf := make([]byte, 5)
rdr.Read(buf)
fmt.Println(buf)
return nil
}
fmt.Println(ReadMember("compare.zip", "compare.zip#fmt-134_fmt-15.zip", fn))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment