diff options
Diffstat (limited to 'src/pkg/compress/flate/deflate.go')
-rw-r--r-- | src/pkg/compress/flate/deflate.go | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/src/pkg/compress/flate/deflate.go b/src/pkg/compress/flate/deflate.go index d357fe361..8c79df0c6 100644 --- a/src/pkg/compress/flate/deflate.go +++ b/src/pkg/compress/flate/deflate.go @@ -416,6 +416,50 @@ func (d *compressor) init(w io.Writer, level int) (err error) { return nil } +var zeroes [32]int +var bzeroes [256]byte + +func (d *compressor) reset(w io.Writer) { + d.w.reset(w) + d.sync = false + d.err = nil + switch d.compressionLevel.chain { + case 0: + // level was NoCompression. + for i := range d.window { + d.window[i] = 0 + } + d.windowEnd = 0 + default: + d.chainHead = -1 + for s := d.hashHead; len(s) > 0; { + n := copy(s, zeroes[:]) + s = s[n:] + } + for s := d.hashPrev; len(s) > 0; s = s[len(zeroes):] { + copy(s, zeroes[:]) + } + d.hashOffset = 1 + + d.index, d.windowEnd = 0, 0 + for s := d.window; len(s) > 0; { + n := copy(s, bzeroes[:]) + s = s[n:] + } + d.blockStart, d.byteAvailable = 0, false + + d.tokens = d.tokens[:maxFlateBlockTokens+1] + for i := 0; i <= maxFlateBlockTokens; i++ { + d.tokens[i] = 0 + } + d.tokens = d.tokens[:0] + d.length = minMatchLength - 1 + d.offset = 0 + d.hash = 0 + d.maxInsertIndex = 0 + } +} + func (d *compressor) close() error { d.sync = true d.step(d) @@ -439,7 +483,6 @@ func (d *compressor) close() error { // If level is in the range [-1, 9] then the error returned will be nil. // Otherwise the error returned will be non-nil. func NewWriter(w io.Writer, level int) (*Writer, error) { - const logWindowSize = logMaxOffsetSize var dw Writer if err := dw.d.init(w, level); err != nil { return nil, err @@ -462,6 +505,7 @@ func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) { zw.Write(dict) zw.Flush() dw.enabled = true + zw.dict = append(zw.dict, dict...) // duplicate dictionary for Reset method. return zw, err } @@ -480,7 +524,8 @@ func (w *dictWriter) Write(b []byte) (n int, err error) { // A Writer takes data written to it and writes the compressed // form of that data to an underlying writer (see NewWriter). type Writer struct { - d compressor + d compressor + dict []byte } // Write writes data to w, which will eventually write the @@ -506,3 +551,21 @@ func (w *Writer) Flush() error { func (w *Writer) Close() error { return w.d.close() } + +// Reset discards the writer's state and makes it equivalent to +// the result of NewWriter or NewWriterDict called with dst +// and w's level and dictionary. +func (w *Writer) Reset(dst io.Writer) { + if dw, ok := w.d.w.w.(*dictWriter); ok { + // w was created with NewWriterDict + dw.w = dst + w.d.reset(dw) + dw.enabled = false + w.Write(w.dict) + w.Flush() + dw.enabled = true + } else { + // w was created with NewWriter + w.d.reset(dst) + } +} |