// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package zip import ( "compress/flate" "io" "io/ioutil" "sync" ) // A Compressor returns a compressing writer, writing to the // provided writer. On Close, any pending data should be flushed. type Compressor func(io.Writer) (io.WriteCloser, error) // Decompressor is a function that wraps a Reader with a decompressing Reader. // The decompressed ReadCloser is returned to callers who open files from // within the archive. These callers are responsible for closing this reader // when they're finished reading. type Decompressor func(io.Reader) io.ReadCloser var ( mu sync.RWMutex // guards compressor and decompressor maps compressors = map[uint16]Compressor{ Store: func(w io.Writer) (io.WriteCloser, error) { return &nopCloser{w}, nil }, Deflate: func(w io.Writer) (io.WriteCloser, error) { return flate.NewWriter(w, 5) }, } decompressors = map[uint16]Decompressor{ Store: ioutil.NopCloser, Deflate: flate.NewReader, } ) // RegisterDecompressor allows custom decompressors for a specified method ID. func RegisterDecompressor(method uint16, d Decompressor) { mu.Lock() defer mu.Unlock() if _, ok := decompressors[method]; ok { panic("decompressor already registered") } decompressors[method] = d } // RegisterCompressor registers custom compressors for a specified method ID. // The common methods Store and Deflate are built in. func RegisterCompressor(method uint16, comp Compressor) { mu.Lock() defer mu.Unlock() if _, ok := compressors[method]; ok { panic("compressor already registered") } compressors[method] = comp } func compressor(method uint16) Compressor { mu.RLock() defer mu.RUnlock() return compressors[method] } func decompressor(method uint16) Decompressor { mu.RLock() defer mu.RUnlock() return decompressors[method] }