mirror of
https://github.com/golang/go
synced 2024-11-13 19:00:25 -07:00
archive/zip: clarify expectations of RegisterCompressor and RegisterDecompressor
Clarify that Compressor and Decompressor callbacks must support being invoked concurrently, but that the writer or reader returned need not be. Updates #8359 Change-Id: Ia407b581dd124185f165c25f5701018a8ce4357a Reviewed-on: https://go-review.googlesource.com/18627 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
1d901f55bd
commit
c736280e22
@ -76,8 +76,7 @@ func ExampleReader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleWriter_RegisterCompressor() {
|
func ExampleWriter_RegisterCompressor() {
|
||||||
// Override the default Deflate compressor with a higher compression
|
// Override the default Deflate compressor with a higher compression level.
|
||||||
// level.
|
|
||||||
|
|
||||||
// Create a buffer to write our archive to.
|
// Create a buffer to write our archive to.
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
@ -85,19 +84,9 @@ func ExampleWriter_RegisterCompressor() {
|
|||||||
// Create a new zip archive.
|
// Create a new zip archive.
|
||||||
w := zip.NewWriter(buf)
|
w := zip.NewWriter(buf)
|
||||||
|
|
||||||
var fw *flate.Writer
|
// Register a custom Deflate compressor.
|
||||||
|
|
||||||
// Register the deflator.
|
|
||||||
w.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
|
w.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
|
||||||
var err error
|
return flate.NewWriter(out, flate.BestCompression)
|
||||||
if fw == nil {
|
|
||||||
// Creating a flate compressor for every file is
|
|
||||||
// expensive, create one and reuse it.
|
|
||||||
fw, err = flate.NewWriter(out, flate.BestCompression)
|
|
||||||
} else {
|
|
||||||
fw.Reset(out)
|
|
||||||
}
|
|
||||||
return fw, err
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Proceed to add files to w.
|
// Proceed to add files to w.
|
||||||
|
@ -118,8 +118,6 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
|
|||||||
// RegisterDecompressor registers or overrides a custom decompressor for a
|
// RegisterDecompressor registers or overrides a custom decompressor for a
|
||||||
// specific method ID. If a decompressor for a given method is not found,
|
// specific method ID. If a decompressor for a given method is not found,
|
||||||
// Reader will default to looking up the decompressor at the package level.
|
// Reader will default to looking up the decompressor at the package level.
|
||||||
//
|
|
||||||
// Must not be called concurrently with Open on any Files in the Reader.
|
|
||||||
func (z *Reader) RegisterDecompressor(method uint16, dcomp Decompressor) {
|
func (z *Reader) RegisterDecompressor(method uint16, dcomp Decompressor) {
|
||||||
if z.decompressors == nil {
|
if z.decompressors == nil {
|
||||||
z.decompressors = make(map[uint16]Decompressor)
|
z.decompressors = make(map[uint16]Decompressor)
|
||||||
|
@ -12,15 +12,19 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Compressor returns a compressing writer, writing to the
|
// A Compressor returns a new compressing writer, writing to w.
|
||||||
// provided writer. On Close, any pending data should be flushed.
|
// The WriteCloser's Close method must be used to flush pending data to w.
|
||||||
type Compressor func(io.Writer) (io.WriteCloser, error)
|
// The Compressor itself must be safe to invoke from multiple goroutines
|
||||||
|
// simultaneously, but each returned writer will be used only by
|
||||||
|
// one goroutine at a time.
|
||||||
|
type Compressor func(w io.Writer) (io.WriteCloser, error)
|
||||||
|
|
||||||
// Decompressor is a function that wraps a Reader with a decompressing Reader.
|
// A Decompressor returns a new decompressing reader, reading from r.
|
||||||
// The decompressed ReadCloser is returned to callers who open files from
|
// The ReadCloser's Close method must be used to release associated resources.
|
||||||
// within the archive. These callers are responsible for closing this reader
|
// The Decompressor itself must be safe to invoke from multiple goroutines
|
||||||
// when they're finished reading.
|
// simultaneously, but each returned reader will be used only by
|
||||||
type Decompressor func(io.Reader) io.ReadCloser
|
// one goroutine at a time.
|
||||||
|
type Decompressor func(r io.Reader) io.ReadCloser
|
||||||
|
|
||||||
var flateWriterPool sync.Pool
|
var flateWriterPool sync.Pool
|
||||||
|
|
||||||
@ -75,14 +79,15 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// RegisterDecompressor allows custom decompressors for a specified method ID.
|
// RegisterDecompressor allows custom decompressors for a specified method ID.
|
||||||
func RegisterDecompressor(method uint16, d Decompressor) {
|
// The common methods Store and Deflate are built in.
|
||||||
|
func RegisterDecompressor(method uint16, dcomp Decompressor) {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
|
|
||||||
if _, ok := decompressors[method]; ok {
|
if _, ok := decompressors[method]; ok {
|
||||||
panic("decompressor already registered")
|
panic("decompressor already registered")
|
||||||
}
|
}
|
||||||
decompressors[method] = d
|
decompressors[method] = dcomp
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterCompressor registers custom compressors for a specified method ID.
|
// RegisterCompressor registers custom compressors for a specified method ID.
|
||||||
|
Loading…
Reference in New Issue
Block a user