summaryrefslogtreecommitdiffstats
path: root/src/compress
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:19:13 +0000
commitccd992355df7192993c666236047820244914598 (patch)
treef00fea65147227b7743083c6148396f74cd66935 /src/compress
parentInitial commit. (diff)
downloadgolang-1.21-ccd992355df7192993c666236047820244914598.tar.xz
golang-1.21-ccd992355df7192993c666236047820244914598.zip
Adding upstream version 1.21.8.upstream/1.21.8
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/compress')
-rw-r--r--src/compress/bzip2/bit_reader.go82
-rw-r--r--src/compress/bzip2/bzip2.go502
-rw-r--r--src/compress/bzip2/bzip2_test.go240
-rw-r--r--src/compress/bzip2/huffman.go237
-rw-r--r--src/compress/bzip2/move_to_front.go53
-rw-r--r--src/compress/bzip2/testdata/Isaac.Newton-Opticks.txt.bz2bin0 -> 132469 bytes
-rw-r--r--src/compress/bzip2/testdata/e.txt.bz2bin0 -> 43149 bytes
-rw-r--r--src/compress/bzip2/testdata/fail-issue5747.bz2bin0 -> 7232 bytes
-rw-r--r--src/compress/bzip2/testdata/pass-random1.binbin0 -> 1024 bytes
-rw-r--r--src/compress/bzip2/testdata/pass-random1.bz2bin0 -> 1309 bytes
-rw-r--r--src/compress/bzip2/testdata/pass-random2.bin1
-rw-r--r--src/compress/bzip2/testdata/pass-random2.bz2bin0 -> 125 bytes
-rw-r--r--src/compress/bzip2/testdata/pass-sawtooth.bz2bin0 -> 2017 bytes
-rw-r--r--src/compress/bzip2/testdata/random.data.bz2bin0 -> 16846 bytes
-rw-r--r--src/compress/flate/deflate.go746
-rw-r--r--src/compress/flate/deflate_test.go1070
-rw-r--r--src/compress/flate/deflatefast.go309
-rw-r--r--src/compress/flate/dict_decoder.go182
-rw-r--r--src/compress/flate/dict_decoder_test.go139
-rw-r--r--src/compress/flate/example_test.go243
-rw-r--r--src/compress/flate/flate_test.go352
-rw-r--r--src/compress/flate/huffman_bit_writer.go701
-rw-r--r--src/compress/flate/huffman_bit_writer_test.go365
-rw-r--r--src/compress/flate/huffman_code.go345
-rw-r--r--src/compress/flate/inflate.go836
-rw-r--r--src/compress/flate/inflate_test.go137
-rw-r--r--src/compress/flate/reader_test.go98
-rw-r--r--src/compress/flate/testdata/huffman-null-max.dyn.expectbin0 -> 78 bytes
-rw-r--r--src/compress/flate/testdata/huffman-null-max.dyn.expect-noinputbin0 -> 78 bytes
-rw-r--r--src/compress/flate/testdata/huffman-null-max.goldenbin0 -> 8204 bytes
-rw-r--r--src/compress/flate/testdata/huffman-null-max.inbin0 -> 65535 bytes
-rw-r--r--src/compress/flate/testdata/huffman-null-max.wb.expectbin0 -> 78 bytes
-rw-r--r--src/compress/flate/testdata/huffman-null-max.wb.expect-noinputbin0 -> 78 bytes
-rw-r--r--src/compress/flate/testdata/huffman-pi.dyn.expectbin0 -> 1696 bytes
-rw-r--r--src/compress/flate/testdata/huffman-pi.dyn.expect-noinputbin0 -> 1696 bytes
-rw-r--r--src/compress/flate/testdata/huffman-pi.goldenbin0 -> 1606 bytes
-rw-r--r--src/compress/flate/testdata/huffman-pi.in1
-rw-r--r--src/compress/flate/testdata/huffman-pi.wb.expectbin0 -> 1696 bytes
-rw-r--r--src/compress/flate/testdata/huffman-pi.wb.expect-noinputbin0 -> 1696 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-1k.dyn.expectbin0 -> 1005 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-1k.dyn.expect-noinputbin0 -> 1054 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-1k.goldenbin0 -> 1005 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-1k.inbin0 -> 1000 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-1k.wb.expectbin0 -> 1005 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-1k.wb.expect-noinputbin0 -> 1054 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-limit.dyn.expectbin0 -> 229 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-limit.dyn.expect-noinputbin0 -> 229 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-limit.goldenbin0 -> 252 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-limit.in4
-rw-r--r--src/compress/flate/testdata/huffman-rand-limit.wb.expectbin0 -> 186 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-limit.wb.expect-noinputbin0 -> 186 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-max.goldenbin0 -> 65540 bytes
-rw-r--r--src/compress/flate/testdata/huffman-rand-max.inbin0 -> 65535 bytes
-rw-r--r--src/compress/flate/testdata/huffman-shifts.dyn.expectbin0 -> 32 bytes
-rw-r--r--src/compress/flate/testdata/huffman-shifts.dyn.expect-noinputbin0 -> 32 bytes
-rw-r--r--src/compress/flate/testdata/huffman-shifts.goldenbin0 -> 1812 bytes
-rw-r--r--src/compress/flate/testdata/huffman-shifts.in2
-rw-r--r--src/compress/flate/testdata/huffman-shifts.wb.expectbin0 -> 32 bytes
-rw-r--r--src/compress/flate/testdata/huffman-shifts.wb.expect-noinputbin0 -> 32 bytes
-rw-r--r--src/compress/flate/testdata/huffman-text-shift.dyn.expectbin0 -> 231 bytes
-rw-r--r--src/compress/flate/testdata/huffman-text-shift.dyn.expect-noinputbin0 -> 231 bytes
-rw-r--r--src/compress/flate/testdata/huffman-text-shift.goldenbin0 -> 231 bytes
-rw-r--r--src/compress/flate/testdata/huffman-text-shift.in14
-rw-r--r--src/compress/flate/testdata/huffman-text-shift.wb.expectbin0 -> 231 bytes
-rw-r--r--src/compress/flate/testdata/huffman-text-shift.wb.expect-noinputbin0 -> 231 bytes
-rw-r--r--src/compress/flate/testdata/huffman-text.dyn.expect1
-rw-r--r--src/compress/flate/testdata/huffman-text.dyn.expect-noinput1
-rw-r--r--src/compress/flate/testdata/huffman-text.golden3
-rw-r--r--src/compress/flate/testdata/huffman-text.in13
-rw-r--r--src/compress/flate/testdata/huffman-text.wb.expect1
-rw-r--r--src/compress/flate/testdata/huffman-text.wb.expect-noinput1
-rw-r--r--src/compress/flate/testdata/huffman-zero.dyn.expectbin0 -> 17 bytes
-rw-r--r--src/compress/flate/testdata/huffman-zero.dyn.expect-noinputbin0 -> 17 bytes
-rw-r--r--src/compress/flate/testdata/huffman-zero.goldenbin0 -> 51 bytes
-rw-r--r--src/compress/flate/testdata/huffman-zero.in1
-rw-r--r--src/compress/flate/testdata/huffman-zero.wb.expectbin0 -> 6 bytes
-rw-r--r--src/compress/flate/testdata/huffman-zero.wb.expect-noinputbin0 -> 6 bytes
-rw-r--r--src/compress/flate/testdata/null-long-match.dyn.expect-noinputbin0 -> 206 bytes
-rw-r--r--src/compress/flate/testdata/null-long-match.wb.expect-noinputbin0 -> 206 bytes
-rw-r--r--src/compress/flate/token.go97
-rw-r--r--src/compress/flate/writer_test.go237
-rw-r--r--src/compress/gzip/example_test.go218
-rw-r--r--src/compress/gzip/fuzz_test.go92
-rw-r--r--src/compress/gzip/gunzip.go290
-rw-r--r--src/compress/gzip/gunzip_test.go587
-rw-r--r--src/compress/gzip/gzip.go250
-rw-r--r--src/compress/gzip/gzip_test.go275
-rw-r--r--src/compress/gzip/issue14937_test.go77
-rw-r--r--src/compress/gzip/testdata/issue6550.gz.base641
-rw-r--r--src/compress/lzw/reader.go290
-rw-r--r--src/compress/lzw/reader_test.go315
-rw-r--r--src/compress/lzw/writer.go293
-rw-r--r--src/compress/lzw/writer_test.go238
-rw-r--r--src/compress/testdata/e.txt1
-rw-r--r--src/compress/testdata/gettysburg.txt29
-rw-r--r--src/compress/testdata/pi.txt1
-rw-r--r--src/compress/zlib/example_test.go37
-rw-r--r--src/compress/zlib/reader.go181
-rw-r--r--src/compress/zlib/reader_test.go186
-rw-r--r--src/compress/zlib/writer.go193
-rw-r--r--src/compress/zlib/writer_test.go224
101 files changed, 10792 insertions, 0 deletions
diff --git a/src/compress/bzip2/bit_reader.go b/src/compress/bzip2/bit_reader.go
new file mode 100644
index 0000000..b451265
--- /dev/null
+++ b/src/compress/bzip2/bit_reader.go
@@ -0,0 +1,82 @@
+// Copyright 2011 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 bzip2
+
+import (
+ "bufio"
+ "io"
+)
+
+// bitReader wraps an io.Reader and provides the ability to read values,
+// bit-by-bit, from it. Its Read* methods don't return the usual error
+// because the error handling was verbose. Instead, any error is kept and can
+// be checked afterwards.
+type bitReader struct {
+ r io.ByteReader
+ n uint64
+ bits uint
+ err error
+}
+
+// newBitReader returns a new bitReader reading from r. If r is not
+// already an io.ByteReader, it will be converted via a bufio.Reader.
+func newBitReader(r io.Reader) bitReader {
+ byter, ok := r.(io.ByteReader)
+ if !ok {
+ byter = bufio.NewReader(r)
+ }
+ return bitReader{r: byter}
+}
+
+// ReadBits64 reads the given number of bits and returns them in the
+// least-significant part of a uint64. In the event of an error, it returns 0
+// and the error can be obtained by calling Err().
+func (br *bitReader) ReadBits64(bits uint) (n uint64) {
+ for bits > br.bits {
+ b, err := br.r.ReadByte()
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ if err != nil {
+ br.err = err
+ return 0
+ }
+ br.n <<= 8
+ br.n |= uint64(b)
+ br.bits += 8
+ }
+
+ // br.n looks like this (assuming that br.bits = 14 and bits = 6):
+ // Bit: 111111
+ // 5432109876543210
+ //
+ // (6 bits, the desired output)
+ // |-----|
+ // V V
+ // 0101101101001110
+ // ^ ^
+ // |------------|
+ // br.bits (num valid bits)
+ //
+ // The next line right shifts the desired bits into the
+ // least-significant places and masks off anything above.
+ n = (br.n >> (br.bits - bits)) & ((1 << bits) - 1)
+ br.bits -= bits
+ return
+}
+
+func (br *bitReader) ReadBits(bits uint) (n int) {
+ n64 := br.ReadBits64(bits)
+ return int(n64)
+}
+
+func (br *bitReader) ReadBit() bool {
+ n := br.ReadBits(1)
+ return n != 0
+}
+
+func (br *bitReader) Err() error {
+ return br.err
+}
diff --git a/src/compress/bzip2/bzip2.go b/src/compress/bzip2/bzip2.go
new file mode 100644
index 0000000..51054cc
--- /dev/null
+++ b/src/compress/bzip2/bzip2.go
@@ -0,0 +1,502 @@
+// Copyright 2011 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 bzip2 implements bzip2 decompression.
+package bzip2
+
+import "io"
+
+// There's no RFC for bzip2. I used the Wikipedia page for reference and a lot
+// of guessing: https://en.wikipedia.org/wiki/Bzip2
+// The source code to pyflate was useful for debugging:
+// http://www.paul.sladen.org/projects/pyflate
+
+// A StructuralError is returned when the bzip2 data is found to be
+// syntactically invalid.
+type StructuralError string
+
+func (s StructuralError) Error() string {
+ return "bzip2 data invalid: " + string(s)
+}
+
+// A reader decompresses bzip2 compressed data.
+type reader struct {
+ br bitReader
+ fileCRC uint32
+ blockCRC uint32
+ wantBlockCRC uint32
+ setupDone bool // true if we have parsed the bzip2 header.
+ blockSize int // blockSize in bytes, i.e. 900 * 1000.
+ eof bool
+ c [256]uint // the ``C'' array for the inverse BWT.
+ tt []uint32 // mirrors the ``tt'' array in the bzip2 source and contains the P array in the upper 24 bits.
+ tPos uint32 // Index of the next output byte in tt.
+
+ preRLE []uint32 // contains the RLE data still to be processed.
+ preRLEUsed int // number of entries of preRLE used.
+ lastByte int // the last byte value seen.
+ byteRepeats uint // the number of repeats of lastByte seen.
+ repeats uint // the number of copies of lastByte to output.
+}
+
+// NewReader returns an io.Reader which decompresses bzip2 data from r.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+func NewReader(r io.Reader) io.Reader {
+ bz2 := new(reader)
+ bz2.br = newBitReader(r)
+ return bz2
+}
+
+const bzip2FileMagic = 0x425a // "BZ"
+const bzip2BlockMagic = 0x314159265359
+const bzip2FinalMagic = 0x177245385090
+
+// setup parses the bzip2 header.
+func (bz2 *reader) setup(needMagic bool) error {
+ br := &bz2.br
+
+ if needMagic {
+ magic := br.ReadBits(16)
+ if magic != bzip2FileMagic {
+ return StructuralError("bad magic value")
+ }
+ }
+
+ t := br.ReadBits(8)
+ if t != 'h' {
+ return StructuralError("non-Huffman entropy encoding")
+ }
+
+ level := br.ReadBits(8)
+ if level < '1' || level > '9' {
+ return StructuralError("invalid compression level")
+ }
+
+ bz2.fileCRC = 0
+ bz2.blockSize = 100 * 1000 * (level - '0')
+ if bz2.blockSize > len(bz2.tt) {
+ bz2.tt = make([]uint32, bz2.blockSize)
+ }
+ return nil
+}
+
+func (bz2 *reader) Read(buf []byte) (n int, err error) {
+ if bz2.eof {
+ return 0, io.EOF
+ }
+
+ if !bz2.setupDone {
+ err = bz2.setup(true)
+ brErr := bz2.br.Err()
+ if brErr != nil {
+ err = brErr
+ }
+ if err != nil {
+ return 0, err
+ }
+ bz2.setupDone = true
+ }
+
+ n, err = bz2.read(buf)
+ brErr := bz2.br.Err()
+ if brErr != nil {
+ err = brErr
+ }
+ return
+}
+
+func (bz2 *reader) readFromBlock(buf []byte) int {
+ // bzip2 is a block based compressor, except that it has a run-length
+ // preprocessing step. The block based nature means that we can
+ // preallocate fixed-size buffers and reuse them. However, the RLE
+ // preprocessing would require allocating huge buffers to store the
+ // maximum expansion. Thus we process blocks all at once, except for
+ // the RLE which we decompress as required.
+ n := 0
+ for (bz2.repeats > 0 || bz2.preRLEUsed < len(bz2.preRLE)) && n < len(buf) {
+ // We have RLE data pending.
+
+ // The run-length encoding works like this:
+ // Any sequence of four equal bytes is followed by a length
+ // byte which contains the number of repeats of that byte to
+ // include. (The number of repeats can be zero.) Because we are
+ // decompressing on-demand our state is kept in the reader
+ // object.
+
+ if bz2.repeats > 0 {
+ buf[n] = byte(bz2.lastByte)
+ n++
+ bz2.repeats--
+ if bz2.repeats == 0 {
+ bz2.lastByte = -1
+ }
+ continue
+ }
+
+ bz2.tPos = bz2.preRLE[bz2.tPos]
+ b := byte(bz2.tPos)
+ bz2.tPos >>= 8
+ bz2.preRLEUsed++
+
+ if bz2.byteRepeats == 3 {
+ bz2.repeats = uint(b)
+ bz2.byteRepeats = 0
+ continue
+ }
+
+ if bz2.lastByte == int(b) {
+ bz2.byteRepeats++
+ } else {
+ bz2.byteRepeats = 0
+ }
+ bz2.lastByte = int(b)
+
+ buf[n] = b
+ n++
+ }
+
+ return n
+}
+
+func (bz2 *reader) read(buf []byte) (int, error) {
+ for {
+ n := bz2.readFromBlock(buf)
+ if n > 0 || len(buf) == 0 {
+ bz2.blockCRC = updateCRC(bz2.blockCRC, buf[:n])
+ return n, nil
+ }
+
+ // End of block. Check CRC.
+ if bz2.blockCRC != bz2.wantBlockCRC {
+ bz2.br.err = StructuralError("block checksum mismatch")
+ return 0, bz2.br.err
+ }
+
+ // Find next block.
+ br := &bz2.br
+ switch br.ReadBits64(48) {
+ default:
+ return 0, StructuralError("bad magic value found")
+
+ case bzip2BlockMagic:
+ // Start of block.
+ err := bz2.readBlock()
+ if err != nil {
+ return 0, err
+ }
+
+ case bzip2FinalMagic:
+ // Check end-of-file CRC.
+ wantFileCRC := uint32(br.ReadBits64(32))
+ if br.err != nil {
+ return 0, br.err
+ }
+ if bz2.fileCRC != wantFileCRC {
+ br.err = StructuralError("file checksum mismatch")
+ return 0, br.err
+ }
+
+ // Skip ahead to byte boundary.
+ // Is there a file concatenated to this one?
+ // It would start with BZ.
+ if br.bits%8 != 0 {
+ br.ReadBits(br.bits % 8)
+ }
+ b, err := br.r.ReadByte()
+ if err == io.EOF {
+ br.err = io.EOF
+ bz2.eof = true
+ return 0, io.EOF
+ }
+ if err != nil {
+ br.err = err
+ return 0, err
+ }
+ z, err := br.r.ReadByte()
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ br.err = err
+ return 0, err
+ }
+ if b != 'B' || z != 'Z' {
+ return 0, StructuralError("bad magic value in continuation file")
+ }
+ if err := bz2.setup(false); err != nil {
+ return 0, err
+ }
+ }
+ }
+}
+
+// readBlock reads a bzip2 block. The magic number should already have been consumed.
+func (bz2 *reader) readBlock() (err error) {
+ br := &bz2.br
+ bz2.wantBlockCRC = uint32(br.ReadBits64(32)) // skip checksum. TODO: check it if we can figure out what it is.
+ bz2.blockCRC = 0
+ bz2.fileCRC = (bz2.fileCRC<<1 | bz2.fileCRC>>31) ^ bz2.wantBlockCRC
+ randomized := br.ReadBits(1)
+ if randomized != 0 {
+ return StructuralError("deprecated randomized files")
+ }
+ origPtr := uint(br.ReadBits(24))
+
+ // If not every byte value is used in the block (i.e., it's text) then
+ // the symbol set is reduced. The symbols used are stored as a
+ // two-level, 16x16 bitmap.
+ symbolRangeUsedBitmap := br.ReadBits(16)
+ symbolPresent := make([]bool, 256)
+ numSymbols := 0
+ for symRange := uint(0); symRange < 16; symRange++ {
+ if symbolRangeUsedBitmap&(1<<(15-symRange)) != 0 {
+ bits := br.ReadBits(16)
+ for symbol := uint(0); symbol < 16; symbol++ {
+ if bits&(1<<(15-symbol)) != 0 {
+ symbolPresent[16*symRange+symbol] = true
+ numSymbols++
+ }
+ }
+ }
+ }
+
+ if numSymbols == 0 {
+ // There must be an EOF symbol.
+ return StructuralError("no symbols in input")
+ }
+
+ // A block uses between two and six different Huffman trees.
+ numHuffmanTrees := br.ReadBits(3)
+ if numHuffmanTrees < 2 || numHuffmanTrees > 6 {
+ return StructuralError("invalid number of Huffman trees")
+ }
+
+ // The Huffman tree can switch every 50 symbols so there's a list of
+ // tree indexes telling us which tree to use for each 50 symbol block.
+ numSelectors := br.ReadBits(15)
+ treeIndexes := make([]uint8, numSelectors)
+
+ // The tree indexes are move-to-front transformed and stored as unary
+ // numbers.
+ mtfTreeDecoder := newMTFDecoderWithRange(numHuffmanTrees)
+ for i := range treeIndexes {
+ c := 0
+ for {
+ inc := br.ReadBits(1)
+ if inc == 0 {
+ break
+ }
+ c++
+ }
+ if c >= numHuffmanTrees {
+ return StructuralError("tree index too large")
+ }
+ treeIndexes[i] = mtfTreeDecoder.Decode(c)
+ }
+
+ // The list of symbols for the move-to-front transform is taken from
+ // the previously decoded symbol bitmap.
+ symbols := make([]byte, numSymbols)
+ nextSymbol := 0
+ for i := 0; i < 256; i++ {
+ if symbolPresent[i] {
+ symbols[nextSymbol] = byte(i)
+ nextSymbol++
+ }
+ }
+ mtf := newMTFDecoder(symbols)
+
+ numSymbols += 2 // to account for RUNA and RUNB symbols
+ huffmanTrees := make([]huffmanTree, numHuffmanTrees)
+
+ // Now we decode the arrays of code-lengths for each tree.
+ lengths := make([]uint8, numSymbols)
+ for i := range huffmanTrees {
+ // The code lengths are delta encoded from a 5-bit base value.
+ length := br.ReadBits(5)
+ for j := range lengths {
+ for {
+ if length < 1 || length > 20 {
+ return StructuralError("Huffman length out of range")
+ }
+ if !br.ReadBit() {
+ break
+ }
+ if br.ReadBit() {
+ length--
+ } else {
+ length++
+ }
+ }
+ lengths[j] = uint8(length)
+ }
+ huffmanTrees[i], err = newHuffmanTree(lengths)
+ if err != nil {
+ return err
+ }
+ }
+
+ selectorIndex := 1 // the next tree index to use
+ if len(treeIndexes) == 0 {
+ return StructuralError("no tree selectors given")
+ }
+ if int(treeIndexes[0]) >= len(huffmanTrees) {
+ return StructuralError("tree selector out of range")
+ }
+ currentHuffmanTree := huffmanTrees[treeIndexes[0]]
+ bufIndex := 0 // indexes bz2.buf, the output buffer.
+ // The output of the move-to-front transform is run-length encoded and
+ // we merge the decoding into the Huffman parsing loop. These two
+ // variables accumulate the repeat count. See the Wikipedia page for
+ // details.
+ repeat := 0
+ repeatPower := 0
+
+ // The `C' array (used by the inverse BWT) needs to be zero initialized.
+ for i := range bz2.c {
+ bz2.c[i] = 0
+ }
+
+ decoded := 0 // counts the number of symbols decoded by the current tree.
+ for {
+ if decoded == 50 {
+ if selectorIndex >= numSelectors {
+ return StructuralError("insufficient selector indices for number of symbols")
+ }
+ if int(treeIndexes[selectorIndex]) >= len(huffmanTrees) {
+ return StructuralError("tree selector out of range")
+ }
+ currentHuffmanTree = huffmanTrees[treeIndexes[selectorIndex]]
+ selectorIndex++
+ decoded = 0
+ }
+
+ v := currentHuffmanTree.Decode(br)
+ decoded++
+
+ if v < 2 {
+ // This is either the RUNA or RUNB symbol.
+ if repeat == 0 {
+ repeatPower = 1
+ }
+ repeat += repeatPower << v
+ repeatPower <<= 1
+
+ // This limit of 2 million comes from the bzip2 source
+ // code. It prevents repeat from overflowing.
+ if repeat > 2*1024*1024 {
+ return StructuralError("repeat count too large")
+ }
+ continue
+ }
+
+ if repeat > 0 {
+ // We have decoded a complete run-length so we need to
+ // replicate the last output symbol.
+ if repeat > bz2.blockSize-bufIndex {
+ return StructuralError("repeats past end of block")
+ }
+ for i := 0; i < repeat; i++ {
+ b := mtf.First()
+ bz2.tt[bufIndex] = uint32(b)
+ bz2.c[b]++
+ bufIndex++
+ }
+ repeat = 0
+ }
+
+ if int(v) == numSymbols-1 {
+ // This is the EOF symbol. Because it's always at the
+ // end of the move-to-front list, and never gets moved
+ // to the front, it has this unique value.
+ break
+ }
+
+ // Since two metasymbols (RUNA and RUNB) have values 0 and 1,
+ // one would expect |v-2| to be passed to the MTF decoder.
+ // However, the front of the MTF list is never referenced as 0,
+ // it's always referenced with a run-length of 1. Thus 0
+ // doesn't need to be encoded and we have |v-1| in the next
+ // line.
+ b := mtf.Decode(int(v - 1))
+ if bufIndex >= bz2.blockSize {
+ return StructuralError("data exceeds block size")
+ }
+ bz2.tt[bufIndex] = uint32(b)
+ bz2.c[b]++
+ bufIndex++
+ }
+
+ if origPtr >= uint(bufIndex) {
+ return StructuralError("origPtr out of bounds")
+ }
+
+ // We have completed the entropy decoding. Now we can perform the
+ // inverse BWT and setup the RLE buffer.
+ bz2.preRLE = bz2.tt[:bufIndex]
+ bz2.preRLEUsed = 0
+ bz2.tPos = inverseBWT(bz2.preRLE, origPtr, bz2.c[:])
+ bz2.lastByte = -1
+ bz2.byteRepeats = 0
+ bz2.repeats = 0
+
+ return nil
+}
+
+// inverseBWT implements the inverse Burrows-Wheeler transform as described in
+// http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-124.pdf, section 4.2.
+// In that document, origPtr is called “I†and c is the “C†array after the
+// first pass over the data. It's an argument here because we merge the first
+// pass with the Huffman decoding.
+//
+// This also implements the “single array†method from the bzip2 source code
+// which leaves the output, still shuffled, in the bottom 8 bits of tt with the
+// index of the next byte in the top 24-bits. The index of the first byte is
+// returned.
+func inverseBWT(tt []uint32, origPtr uint, c []uint) uint32 {
+ sum := uint(0)
+ for i := 0; i < 256; i++ {
+ sum += c[i]
+ c[i] = sum - c[i]
+ }
+
+ for i := range tt {
+ b := tt[i] & 0xff
+ tt[c[b]] |= uint32(i) << 8
+ c[b]++
+ }
+
+ return tt[origPtr] >> 8
+}
+
+// This is a standard CRC32 like in hash/crc32 except that all the shifts are reversed,
+// causing the bits in the input to be processed in the reverse of the usual order.
+
+var crctab [256]uint32
+
+func init() {
+ const poly = 0x04C11DB7
+ for i := range crctab {
+ crc := uint32(i) << 24
+ for j := 0; j < 8; j++ {
+ if crc&0x80000000 != 0 {
+ crc = (crc << 1) ^ poly
+ } else {
+ crc <<= 1
+ }
+ }
+ crctab[i] = crc
+ }
+}
+
+// updateCRC updates the crc value to incorporate the data in b.
+// The initial value is 0.
+func updateCRC(val uint32, b []byte) uint32 {
+ crc := ^val
+ for _, v := range b {
+ crc = crctab[byte(crc>>24)^v] ^ (crc << 8)
+ }
+ return ^crc
+}
diff --git a/src/compress/bzip2/bzip2_test.go b/src/compress/bzip2/bzip2_test.go
new file mode 100644
index 0000000..e6065cb
--- /dev/null
+++ b/src/compress/bzip2/bzip2_test.go
@@ -0,0 +1,240 @@
+// Copyright 2011 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 bzip2
+
+import (
+ "bytes"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "os"
+ "testing"
+)
+
+func mustDecodeHex(s string) []byte {
+ b, err := hex.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+func mustLoadFile(f string) []byte {
+ b, err := os.ReadFile(f)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+func trim(b []byte) string {
+ const limit = 1024
+ if len(b) < limit {
+ return fmt.Sprintf("%q", b)
+ }
+ return fmt.Sprintf("%q...", b[:limit])
+}
+
+func TestReader(t *testing.T) {
+ var vectors = []struct {
+ desc string
+ input []byte
+ output []byte
+ fail bool
+ }{{
+ desc: "hello world",
+ input: mustDecodeHex("" +
+ "425a68393141592653594eece83600000251800010400006449080200031064c" +
+ "4101a7a9a580bb9431f8bb9229c28482776741b0",
+ ),
+ output: []byte("hello world\n"),
+ }, {
+ desc: "concatenated files",
+ input: mustDecodeHex("" +
+ "425a68393141592653594eece83600000251800010400006449080200031064c" +
+ "4101a7a9a580bb9431f8bb9229c28482776741b0425a68393141592653594eec" +
+ "e83600000251800010400006449080200031064c4101a7a9a580bb9431f8bb92" +
+ "29c28482776741b0",
+ ),
+ output: []byte("hello world\nhello world\n"),
+ }, {
+ desc: "32B zeros",
+ input: mustDecodeHex("" +
+ "425a6839314159265359b5aa5098000000600040000004200021008283177245" +
+ "385090b5aa5098",
+ ),
+ output: make([]byte, 32),
+ }, {
+ desc: "1MiB zeros",
+ input: mustDecodeHex("" +
+ "425a683931415926535938571ce50008084000c0040008200030cc0529a60806" +
+ "c4201e2ee48a70a12070ae39ca",
+ ),
+ output: make([]byte, 1<<20),
+ }, {
+ desc: "random data",
+ input: mustLoadFile("testdata/pass-random1.bz2"),
+ output: mustLoadFile("testdata/pass-random1.bin"),
+ }, {
+ desc: "random data - full symbol range",
+ input: mustLoadFile("testdata/pass-random2.bz2"),
+ output: mustLoadFile("testdata/pass-random2.bin"),
+ }, {
+ desc: "random data - uses RLE1 stage",
+ input: mustDecodeHex("" +
+ "425a6839314159265359d992d0f60000137dfe84020310091c1e280e100e0428" +
+ "01099210094806c0110002e70806402000546034000034000000f28300000320" +
+ "00d3403264049270eb7a9280d308ca06ad28f6981bee1bf8160727c7364510d7" +
+ "3a1e123083421b63f031f63993a0f40051fbf177245385090d992d0f60",
+ ),
+ output: mustDecodeHex("" +
+ "92d5652616ac444a4a04af1a8a3964aca0450d43d6cf233bd03233f4ba92f871" +
+ "9e6c2a2bd4f5f88db07ecd0da3a33b263483db9b2c158786ad6363be35d17335" +
+ "ba",
+ ),
+ }, {
+ desc: "1MiB sawtooth",
+ input: mustLoadFile("testdata/pass-sawtooth.bz2"),
+ output: func() []byte {
+ b := make([]byte, 1<<20)
+ for i := range b {
+ b[i] = byte(i)
+ }
+ return b
+ }(),
+ }, {
+ desc: "RLE2 buffer overrun - issue 5747",
+ input: mustLoadFile("testdata/fail-issue5747.bz2"),
+ fail: true,
+ }, {
+ desc: "out-of-range selector - issue 8363",
+ input: mustDecodeHex("" +
+ "425a68393141592653594eece83600000251800010400006449080200031064c" +
+ "4101a7a9a580bb943117724538509000000000",
+ ),
+ fail: true,
+ }, {
+ desc: "bad block size - issue 13941",
+ input: mustDecodeHex("" +
+ "425a683131415926535936dc55330063ffc0006000200020a40830008b0008b8" +
+ "bb9229c28481b6e2a998",
+ ),
+ fail: true,
+ }, {
+ desc: "bad huffman delta",
+ input: mustDecodeHex("" +
+ "425a6836314159265359b1f7404b000000400040002000217d184682ee48a70a" +
+ "12163ee80960",
+ ),
+ fail: true,
+ }}
+
+ for i, v := range vectors {
+ rd := NewReader(bytes.NewReader(v.input))
+ buf, err := io.ReadAll(rd)
+
+ if fail := bool(err != nil); fail != v.fail {
+ if fail {
+ t.Errorf("test %d (%s), unexpected failure: %v", i, v.desc, err)
+ } else {
+ t.Errorf("test %d (%s), unexpected success", i, v.desc)
+ }
+ }
+ if !v.fail && !bytes.Equal(buf, v.output) {
+ t.Errorf("test %d (%s), output mismatch:\ngot %s\nwant %s", i, v.desc, trim(buf), trim(v.output))
+ }
+ }
+}
+
+func TestBitReader(t *testing.T) {
+ var vectors = []struct {
+ nbits uint // Number of bits to read
+ value int // Expected output value (0 for error)
+ fail bool // Expected operation failure?
+ }{
+ {nbits: 1, value: 1},
+ {nbits: 1, value: 0},
+ {nbits: 1, value: 1},
+ {nbits: 5, value: 11},
+ {nbits: 32, value: 0x12345678},
+ {nbits: 15, value: 14495},
+ {nbits: 3, value: 6},
+ {nbits: 6, value: 13},
+ {nbits: 1, fail: true},
+ }
+
+ rd := bytes.NewReader([]byte{0xab, 0x12, 0x34, 0x56, 0x78, 0x71, 0x3f, 0x8d})
+ br := newBitReader(rd)
+ for i, v := range vectors {
+ val := br.ReadBits(v.nbits)
+ if fail := bool(br.err != nil); fail != v.fail {
+ if fail {
+ t.Errorf("test %d, unexpected failure: ReadBits(%d) = %v", i, v.nbits, br.err)
+ } else {
+ t.Errorf("test %d, unexpected success: ReadBits(%d) = nil", i, v.nbits)
+ }
+ }
+ if !v.fail && val != v.value {
+ t.Errorf("test %d, mismatching value: ReadBits(%d) = %d, want %d", i, v.nbits, val, v.value)
+ }
+ }
+}
+
+func TestMTF(t *testing.T) {
+ var vectors = []struct {
+ idx int // Input index
+ sym uint8 // Expected output symbol
+ }{
+ {idx: 1, sym: 1}, // [1 0 2 3 4]
+ {idx: 0, sym: 1}, // [1 0 2 3 4]
+ {idx: 1, sym: 0}, // [0 1 2 3 4]
+ {idx: 4, sym: 4}, // [4 0 1 2 3]
+ {idx: 1, sym: 0}, // [0 4 1 2 3]
+ }
+
+ mtf := newMTFDecoderWithRange(5)
+ for i, v := range vectors {
+ sym := mtf.Decode(v.idx)
+ t.Log(mtf)
+ if sym != v.sym {
+ t.Errorf("test %d, symbol mismatch: Decode(%d) = %d, want %d", i, v.idx, sym, v.sym)
+ }
+ }
+}
+
+func TestZeroRead(t *testing.T) {
+ b := mustDecodeHex("425a6839314159265359b5aa5098000000600040000004200021008283177245385090b5aa5098")
+ r := NewReader(bytes.NewReader(b))
+ if n, err := r.Read(nil); n != 0 || err != nil {
+ t.Errorf("Read(nil) = (%d, %v), want (0, nil)", n, err)
+ }
+}
+
+var (
+ digits = mustLoadFile("testdata/e.txt.bz2")
+ newton = mustLoadFile("testdata/Isaac.Newton-Opticks.txt.bz2")
+ random = mustLoadFile("testdata/random.data.bz2")
+)
+
+func benchmarkDecode(b *testing.B, compressed []byte) {
+ // Determine the uncompressed size of testfile.
+ uncompressedSize, err := io.Copy(io.Discard, NewReader(bytes.NewReader(compressed)))
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ b.SetBytes(uncompressedSize)
+ b.ReportAllocs()
+ b.ResetTimer()
+
+ for i := 0; i < b.N; i++ {
+ r := bytes.NewReader(compressed)
+ io.Copy(io.Discard, NewReader(r))
+ }
+}
+
+func BenchmarkDecodeDigits(b *testing.B) { benchmarkDecode(b, digits) }
+func BenchmarkDecodeNewton(b *testing.B) { benchmarkDecode(b, newton) }
+func BenchmarkDecodeRand(b *testing.B) { benchmarkDecode(b, random) }
diff --git a/src/compress/bzip2/huffman.go b/src/compress/bzip2/huffman.go
new file mode 100644
index 0000000..447fc4d
--- /dev/null
+++ b/src/compress/bzip2/huffman.go
@@ -0,0 +1,237 @@
+// Copyright 2011 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 bzip2
+
+import "sort"
+
+// A huffmanTree is a binary tree which is navigated, bit-by-bit to reach a
+// symbol.
+type huffmanTree struct {
+ // nodes contains all the non-leaf nodes in the tree. nodes[0] is the
+ // root of the tree and nextNode contains the index of the next element
+ // of nodes to use when the tree is being constructed.
+ nodes []huffmanNode
+ nextNode int
+}
+
+// A huffmanNode is a node in the tree. left and right contain indexes into the
+// nodes slice of the tree. If left or right is invalidNodeValue then the child
+// is a left node and its value is in leftValue/rightValue.
+//
+// The symbols are uint16s because bzip2 encodes not only MTF indexes in the
+// tree, but also two magic values for run-length encoding and an EOF symbol.
+// Thus there are more than 256 possible symbols.
+type huffmanNode struct {
+ left, right uint16
+ leftValue, rightValue uint16
+}
+
+// invalidNodeValue is an invalid index which marks a leaf node in the tree.
+const invalidNodeValue = 0xffff
+
+// Decode reads bits from the given bitReader and navigates the tree until a
+// symbol is found.
+func (t *huffmanTree) Decode(br *bitReader) (v uint16) {
+ nodeIndex := uint16(0) // node 0 is the root of the tree.
+
+ for {
+ node := &t.nodes[nodeIndex]
+
+ var bit uint16
+ if br.bits > 0 {
+ // Get next bit - fast path.
+ br.bits--
+ bit = uint16(br.n>>(br.bits&63)) & 1
+ } else {
+ // Get next bit - slow path.
+ // Use ReadBits to retrieve a single bit
+ // from the underling io.ByteReader.
+ bit = uint16(br.ReadBits(1))
+ }
+
+ // Trick a compiler into generating conditional move instead of branch,
+ // by making both loads unconditional.
+ l, r := node.left, node.right
+
+ if bit == 1 {
+ nodeIndex = l
+ } else {
+ nodeIndex = r
+ }
+
+ if nodeIndex == invalidNodeValue {
+ // We found a leaf. Use the value of bit to decide
+ // whether is a left or a right value.
+ l, r := node.leftValue, node.rightValue
+ if bit == 1 {
+ v = l
+ } else {
+ v = r
+ }
+ return
+ }
+ }
+}
+
+// newHuffmanTree builds a Huffman tree from a slice containing the code
+// lengths of each symbol. The maximum code length is 32 bits.
+func newHuffmanTree(lengths []uint8) (huffmanTree, error) {
+ // There are many possible trees that assign the same code length to
+ // each symbol (consider reflecting a tree down the middle, for
+ // example). Since the code length assignments determine the
+ // efficiency of the tree, each of these trees is equally good. In
+ // order to minimize the amount of information needed to build a tree
+ // bzip2 uses a canonical tree so that it can be reconstructed given
+ // only the code length assignments.
+
+ if len(lengths) < 2 {
+ panic("newHuffmanTree: too few symbols")
+ }
+
+ var t huffmanTree
+
+ // First we sort the code length assignments by ascending code length,
+ // using the symbol value to break ties.
+ pairs := make([]huffmanSymbolLengthPair, len(lengths))
+ for i, length := range lengths {
+ pairs[i].value = uint16(i)
+ pairs[i].length = length
+ }
+
+ sort.Slice(pairs, func(i, j int) bool {
+ if pairs[i].length < pairs[j].length {
+ return true
+ }
+ if pairs[i].length > pairs[j].length {
+ return false
+ }
+ if pairs[i].value < pairs[j].value {
+ return true
+ }
+ return false
+ })
+
+ // Now we assign codes to the symbols, starting with the longest code.
+ // We keep the codes packed into a uint32, at the most-significant end.
+ // So branches are taken from the MSB downwards. This makes it easy to
+ // sort them later.
+ code := uint32(0)
+ length := uint8(32)
+
+ codes := make([]huffmanCode, len(lengths))
+ for i := len(pairs) - 1; i >= 0; i-- {
+ if length > pairs[i].length {
+ length = pairs[i].length
+ }
+ codes[i].code = code
+ codes[i].codeLen = length
+ codes[i].value = pairs[i].value
+ // We need to 'increment' the code, which means treating |code|
+ // like a |length| bit number.
+ code += 1 << (32 - length)
+ }
+
+ // Now we can sort by the code so that the left half of each branch are
+ // grouped together, recursively.
+ sort.Slice(codes, func(i, j int) bool {
+ return codes[i].code < codes[j].code
+ })
+
+ t.nodes = make([]huffmanNode, len(codes))
+ _, err := buildHuffmanNode(&t, codes, 0)
+ return t, err
+}
+
+// huffmanSymbolLengthPair contains a symbol and its code length.
+type huffmanSymbolLengthPair struct {
+ value uint16
+ length uint8
+}
+
+// huffmanCode contains a symbol, its code and code length.
+type huffmanCode struct {
+ code uint32
+ codeLen uint8
+ value uint16
+}
+
+// buildHuffmanNode takes a slice of sorted huffmanCodes and builds a node in
+// the Huffman tree at the given level. It returns the index of the newly
+// constructed node.
+func buildHuffmanNode(t *huffmanTree, codes []huffmanCode, level uint32) (nodeIndex uint16, err error) {
+ test := uint32(1) << (31 - level)
+
+ // We have to search the list of codes to find the divide between the left and right sides.
+ firstRightIndex := len(codes)
+ for i, code := range codes {
+ if code.code&test != 0 {
+ firstRightIndex = i
+ break
+ }
+ }
+
+ left := codes[:firstRightIndex]
+ right := codes[firstRightIndex:]
+
+ if len(left) == 0 || len(right) == 0 {
+ // There is a superfluous level in the Huffman tree indicating
+ // a bug in the encoder. However, this bug has been observed in
+ // the wild so we handle it.
+
+ // If this function was called recursively then we know that
+ // len(codes) >= 2 because, otherwise, we would have hit the
+ // "leaf node" case, below, and not recurred.
+ //
+ // However, for the initial call it's possible that len(codes)
+ // is zero or one. Both cases are invalid because a zero length
+ // tree cannot encode anything and a length-1 tree can only
+ // encode EOF and so is superfluous. We reject both.
+ if len(codes) < 2 {
+ return 0, StructuralError("empty Huffman tree")
+ }
+
+ // In this case the recursion doesn't always reduce the length
+ // of codes so we need to ensure termination via another
+ // mechanism.
+ if level == 31 {
+ // Since len(codes) >= 2 the only way that the values
+ // can match at all 32 bits is if they are equal, which
+ // is invalid. This ensures that we never enter
+ // infinite recursion.
+ return 0, StructuralError("equal symbols in Huffman tree")
+ }
+
+ if len(left) == 0 {
+ return buildHuffmanNode(t, right, level+1)
+ }
+ return buildHuffmanNode(t, left, level+1)
+ }
+
+ nodeIndex = uint16(t.nextNode)
+ node := &t.nodes[t.nextNode]
+ t.nextNode++
+
+ if len(left) == 1 {
+ // leaf node
+ node.left = invalidNodeValue
+ node.leftValue = left[0].value
+ } else {
+ node.left, err = buildHuffmanNode(t, left, level+1)
+ }
+
+ if err != nil {
+ return
+ }
+
+ if len(right) == 1 {
+ // leaf node
+ node.right = invalidNodeValue
+ node.rightValue = right[0].value
+ } else {
+ node.right, err = buildHuffmanNode(t, right, level+1)
+ }
+
+ return
+}
diff --git a/src/compress/bzip2/move_to_front.go b/src/compress/bzip2/move_to_front.go
new file mode 100644
index 0000000..526dfb3
--- /dev/null
+++ b/src/compress/bzip2/move_to_front.go
@@ -0,0 +1,53 @@
+// Copyright 2011 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 bzip2
+
+// moveToFrontDecoder implements a move-to-front list. Such a list is an
+// efficient way to transform a string with repeating elements into one with
+// many small valued numbers, which is suitable for entropy encoding. It works
+// by starting with an initial list of symbols and references symbols by their
+// index into that list. When a symbol is referenced, it's moved to the front
+// of the list. Thus, a repeated symbol ends up being encoded with many zeros,
+// as the symbol will be at the front of the list after the first access.
+type moveToFrontDecoder []byte
+
+// newMTFDecoder creates a move-to-front decoder with an explicit initial list
+// of symbols.
+func newMTFDecoder(symbols []byte) moveToFrontDecoder {
+ if len(symbols) > 256 {
+ panic("too many symbols")
+ }
+ return moveToFrontDecoder(symbols)
+}
+
+// newMTFDecoderWithRange creates a move-to-front decoder with an initial
+// symbol list of 0...n-1.
+func newMTFDecoderWithRange(n int) moveToFrontDecoder {
+ if n > 256 {
+ panic("newMTFDecoderWithRange: cannot have > 256 symbols")
+ }
+
+ m := make([]byte, n)
+ for i := 0; i < n; i++ {
+ m[i] = byte(i)
+ }
+ return moveToFrontDecoder(m)
+}
+
+func (m moveToFrontDecoder) Decode(n int) (b byte) {
+ // Implement move-to-front with a simple copy. This approach
+ // beats more sophisticated approaches in benchmarking, probably
+ // because it has high locality of reference inside of a
+ // single cache line (most move-to-front operations have n < 64).
+ b = m[n]
+ copy(m[1:], m[:n])
+ m[0] = b
+ return
+}
+
+// First returns the symbol at the front of the list.
+func (m moveToFrontDecoder) First() byte {
+ return m[0]
+}
diff --git a/src/compress/bzip2/testdata/Isaac.Newton-Opticks.txt.bz2 b/src/compress/bzip2/testdata/Isaac.Newton-Opticks.txt.bz2
new file mode 100644
index 0000000..6c56de3
--- /dev/null
+++ b/src/compress/bzip2/testdata/Isaac.Newton-Opticks.txt.bz2
Binary files differ
diff --git a/src/compress/bzip2/testdata/e.txt.bz2 b/src/compress/bzip2/testdata/e.txt.bz2
new file mode 100644
index 0000000..65bf3b4
--- /dev/null
+++ b/src/compress/bzip2/testdata/e.txt.bz2
Binary files differ
diff --git a/src/compress/bzip2/testdata/fail-issue5747.bz2 b/src/compress/bzip2/testdata/fail-issue5747.bz2
new file mode 100644
index 0000000..2bf2b6a
--- /dev/null
+++ b/src/compress/bzip2/testdata/fail-issue5747.bz2
Binary files differ
diff --git a/src/compress/bzip2/testdata/pass-random1.bin b/src/compress/bzip2/testdata/pass-random1.bin
new file mode 100644
index 0000000..6e17879
--- /dev/null
+++ b/src/compress/bzip2/testdata/pass-random1.bin
Binary files differ
diff --git a/src/compress/bzip2/testdata/pass-random1.bz2 b/src/compress/bzip2/testdata/pass-random1.bz2
new file mode 100644
index 0000000..f6a9dc7
--- /dev/null
+++ b/src/compress/bzip2/testdata/pass-random1.bz2
Binary files differ
diff --git a/src/compress/bzip2/testdata/pass-random2.bin b/src/compress/bzip2/testdata/pass-random2.bin
new file mode 100644
index 0000000..f152d40
--- /dev/null
+++ b/src/compress/bzip2/testdata/pass-random2.bin
@@ -0,0 +1 @@
+’Õe&¬DJJ¯Š9d¬ E CÖÏ#;Ð23ôº’øqžl*+Ôõø°~Í ££;&4ƒÛ›,‡†­cc¾5Ñs5º \ No newline at end of file
diff --git a/src/compress/bzip2/testdata/pass-random2.bz2 b/src/compress/bzip2/testdata/pass-random2.bz2
new file mode 100644
index 0000000..91ef775
--- /dev/null
+++ b/src/compress/bzip2/testdata/pass-random2.bz2
Binary files differ
diff --git a/src/compress/bzip2/testdata/pass-sawtooth.bz2 b/src/compress/bzip2/testdata/pass-sawtooth.bz2
new file mode 100644
index 0000000..579a378
--- /dev/null
+++ b/src/compress/bzip2/testdata/pass-sawtooth.bz2
Binary files differ
diff --git a/src/compress/bzip2/testdata/random.data.bz2 b/src/compress/bzip2/testdata/random.data.bz2
new file mode 100644
index 0000000..1ef2300
--- /dev/null
+++ b/src/compress/bzip2/testdata/random.data.bz2
Binary files differ
diff --git a/src/compress/flate/deflate.go b/src/compress/flate/deflate.go
new file mode 100644
index 0000000..b53764b
--- /dev/null
+++ b/src/compress/flate/deflate.go
@@ -0,0 +1,746 @@
+// Copyright 2009 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 flate
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "math"
+)
+
+const (
+ NoCompression = 0
+ BestSpeed = 1
+ BestCompression = 9
+ DefaultCompression = -1
+
+ // HuffmanOnly disables Lempel-Ziv match searching and only performs Huffman
+ // entropy encoding. This mode is useful in compressing data that has
+ // already been compressed with an LZ style algorithm (e.g. Snappy or LZ4)
+ // that lacks an entropy encoder. Compression gains are achieved when
+ // certain bytes in the input stream occur more frequently than others.
+ //
+ // Note that HuffmanOnly produces a compressed output that is
+ // RFC 1951 compliant. That is, any valid DEFLATE decompressor will
+ // continue to be able to decompress this output.
+ HuffmanOnly = -2
+)
+
+const (
+ logWindowSize = 15
+ windowSize = 1 << logWindowSize
+ windowMask = windowSize - 1
+
+ // The LZ77 step produces a sequence of literal tokens and <length, offset>
+ // pair tokens. The offset is also known as distance. The underlying wire
+ // format limits the range of lengths and offsets. For example, there are
+ // 256 legitimate lengths: those in the range [3, 258]. This package's
+ // compressor uses a higher minimum match length, enabling optimizations
+ // such as finding matches via 32-bit loads and compares.
+ baseMatchLength = 3 // The smallest match length per the RFC section 3.2.5
+ minMatchLength = 4 // The smallest match length that the compressor actually emits
+ maxMatchLength = 258 // The largest match length
+ baseMatchOffset = 1 // The smallest match offset
+ maxMatchOffset = 1 << 15 // The largest match offset
+
+ // The maximum number of tokens we put into a single flate block, just to
+ // stop things from getting too large.
+ maxFlateBlockTokens = 1 << 14
+ maxStoreBlockSize = 65535
+ hashBits = 17 // After 17 performance degrades
+ hashSize = 1 << hashBits
+ hashMask = (1 << hashBits) - 1
+ maxHashOffset = 1 << 24
+
+ skipNever = math.MaxInt32
+)
+
+type compressionLevel struct {
+ level, good, lazy, nice, chain, fastSkipHashing int
+}
+
+var levels = []compressionLevel{
+ {0, 0, 0, 0, 0, 0}, // NoCompression.
+ {1, 0, 0, 0, 0, 0}, // BestSpeed uses a custom algorithm; see deflatefast.go.
+ // For levels 2-3 we don't bother trying with lazy matches.
+ {2, 4, 0, 16, 8, 5},
+ {3, 4, 0, 32, 32, 6},
+ // Levels 4-9 use increasingly more lazy matching
+ // and increasingly stringent conditions for "good enough".
+ {4, 4, 4, 16, 16, skipNever},
+ {5, 8, 16, 32, 32, skipNever},
+ {6, 8, 16, 128, 128, skipNever},
+ {7, 8, 32, 128, 256, skipNever},
+ {8, 32, 128, 258, 1024, skipNever},
+ {9, 32, 258, 258, 4096, skipNever},
+}
+
+type compressor struct {
+ compressionLevel
+
+ w *huffmanBitWriter
+ bulkHasher func([]byte, []uint32)
+
+ // compression algorithm
+ fill func(*compressor, []byte) int // copy data to window
+ step func(*compressor) // process window
+ sync bool // requesting flush
+ bestSpeed *deflateFast // Encoder for BestSpeed
+
+ // Input hash chains
+ // hashHead[hashValue] contains the largest inputIndex with the specified hash value
+ // If hashHead[hashValue] is within the current window, then
+ // hashPrev[hashHead[hashValue] & windowMask] contains the previous index
+ // with the same hash value.
+ chainHead int
+ hashHead [hashSize]uint32
+ hashPrev [windowSize]uint32
+ hashOffset int
+
+ // input window: unprocessed data is window[index:windowEnd]
+ index int
+ window []byte
+ windowEnd int
+ blockStart int // window index where current tokens start
+ byteAvailable bool // if true, still need to process window[index-1].
+
+ // queued output tokens
+ tokens []token
+
+ // deflate state
+ length int
+ offset int
+ maxInsertIndex int
+ err error
+
+ // hashMatch must be able to contain hashes for the maximum match length.
+ hashMatch [maxMatchLength - 1]uint32
+}
+
+func (d *compressor) fillDeflate(b []byte) int {
+ if d.index >= 2*windowSize-(minMatchLength+maxMatchLength) {
+ // shift the window by windowSize
+ copy(d.window, d.window[windowSize:2*windowSize])
+ d.index -= windowSize
+ d.windowEnd -= windowSize
+ if d.blockStart >= windowSize {
+ d.blockStart -= windowSize
+ } else {
+ d.blockStart = math.MaxInt32
+ }
+ d.hashOffset += windowSize
+ if d.hashOffset > maxHashOffset {
+ delta := d.hashOffset - 1
+ d.hashOffset -= delta
+ d.chainHead -= delta
+
+ // Iterate over slices instead of arrays to avoid copying
+ // the entire table onto the stack (Issue #18625).
+ for i, v := range d.hashPrev[:] {
+ if int(v) > delta {
+ d.hashPrev[i] = uint32(int(v) - delta)
+ } else {
+ d.hashPrev[i] = 0
+ }
+ }
+ for i, v := range d.hashHead[:] {
+ if int(v) > delta {
+ d.hashHead[i] = uint32(int(v) - delta)
+ } else {
+ d.hashHead[i] = 0
+ }
+ }
+ }
+ }
+ n := copy(d.window[d.windowEnd:], b)
+ d.windowEnd += n
+ return n
+}
+
+func (d *compressor) writeBlock(tokens []token, index int) error {
+ if index > 0 {
+ var window []byte
+ if d.blockStart <= index {
+ window = d.window[d.blockStart:index]
+ }
+ d.blockStart = index
+ d.w.writeBlock(tokens, false, window)
+ return d.w.err
+ }
+ return nil
+}
+
+// fillWindow will fill the current window with the supplied
+// dictionary and calculate all hashes.
+// This is much faster than doing a full encode.
+// Should only be used after a reset.
+func (d *compressor) fillWindow(b []byte) {
+ // Do not fill window if we are in store-only mode.
+ if d.compressionLevel.level < 2 {
+ return
+ }
+ if d.index != 0 || d.windowEnd != 0 {
+ panic("internal error: fillWindow called with stale data")
+ }
+
+ // If we are given too much, cut it.
+ if len(b) > windowSize {
+ b = b[len(b)-windowSize:]
+ }
+ // Add all to window.
+ n := copy(d.window, b)
+
+ // Calculate 256 hashes at the time (more L1 cache hits)
+ loops := (n + 256 - minMatchLength) / 256
+ for j := 0; j < loops; j++ {
+ index := j * 256
+ end := index + 256 + minMatchLength - 1
+ if end > n {
+ end = n
+ }
+ toCheck := d.window[index:end]
+ dstSize := len(toCheck) - minMatchLength + 1
+
+ if dstSize <= 0 {
+ continue
+ }
+
+ dst := d.hashMatch[:dstSize]
+ d.bulkHasher(toCheck, dst)
+ for i, val := range dst {
+ di := i + index
+ hh := &d.hashHead[val&hashMask]
+ // Get previous value with the same hash.
+ // Our chain should point to the previous value.
+ d.hashPrev[di&windowMask] = *hh
+ // Set the head of the hash chain to us.
+ *hh = uint32(di + d.hashOffset)
+ }
+ }
+ // Update window information.
+ d.windowEnd = n
+ d.index = n
+}
+
+// Try to find a match starting at index whose length is greater than prevSize.
+// We only look at chainCount possibilities before giving up.
+func (d *compressor) findMatch(pos int, prevHead int, prevLength int, lookahead int) (length, offset int, ok bool) {
+ minMatchLook := maxMatchLength
+ if lookahead < minMatchLook {
+ minMatchLook = lookahead
+ }
+
+ win := d.window[0 : pos+minMatchLook]
+
+ // We quit when we get a match that's at least nice long
+ nice := len(win) - pos
+ if d.nice < nice {
+ nice = d.nice
+ }
+
+ // If we've got a match that's good enough, only look in 1/4 the chain.
+ tries := d.chain
+ length = prevLength
+ if length >= d.good {
+ tries >>= 2
+ }
+
+ wEnd := win[pos+length]
+ wPos := win[pos:]
+ minIndex := pos - windowSize
+
+ for i := prevHead; tries > 0; tries-- {
+ if wEnd == win[i+length] {
+ n := matchLen(win[i:], wPos, minMatchLook)
+
+ if n > length && (n > minMatchLength || pos-i <= 4096) {
+ length = n
+ offset = pos - i
+ ok = true
+ if n >= nice {
+ // The match is good enough that we don't try to find a better one.
+ break
+ }
+ wEnd = win[pos+n]
+ }
+ }
+ if i == minIndex {
+ // hashPrev[i & windowMask] has already been overwritten, so stop now.
+ break
+ }
+ i = int(d.hashPrev[i&windowMask]) - d.hashOffset
+ if i < minIndex || i < 0 {
+ break
+ }
+ }
+ return
+}
+
+func (d *compressor) writeStoredBlock(buf []byte) error {
+ if d.w.writeStoredHeader(len(buf), false); d.w.err != nil {
+ return d.w.err
+ }
+ d.w.writeBytes(buf)
+ return d.w.err
+}
+
+const hashmul = 0x1e35a7bd
+
+// hash4 returns a hash representation of the first 4 bytes
+// of the supplied slice.
+// The caller must ensure that len(b) >= 4.
+func hash4(b []byte) uint32 {
+ return ((uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24) * hashmul) >> (32 - hashBits)
+}
+
+// bulkHash4 will compute hashes using the same
+// algorithm as hash4.
+func bulkHash4(b []byte, dst []uint32) {
+ if len(b) < minMatchLength {
+ return
+ }
+ hb := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+ dst[0] = (hb * hashmul) >> (32 - hashBits)
+ end := len(b) - minMatchLength + 1
+ for i := 1; i < end; i++ {
+ hb = (hb << 8) | uint32(b[i+3])
+ dst[i] = (hb * hashmul) >> (32 - hashBits)
+ }
+}
+
+// matchLen returns the number of matching bytes in a and b
+// up to length 'max'. Both slices must be at least 'max'
+// bytes in size.
+func matchLen(a, b []byte, max int) int {
+ a = a[:max]
+ b = b[:len(a)]
+ for i, av := range a {
+ if b[i] != av {
+ return i
+ }
+ }
+ return max
+}
+
+// encSpeed will compress and store the currently added data,
+// if enough has been accumulated or we at the end of the stream.
+// Any error that occurred will be in d.err
+func (d *compressor) encSpeed() {
+ // We only compress if we have maxStoreBlockSize.
+ if d.windowEnd < maxStoreBlockSize {
+ if !d.sync {
+ return
+ }
+
+ // Handle small sizes.
+ if d.windowEnd < 128 {
+ switch {
+ case d.windowEnd == 0:
+ return
+ case d.windowEnd <= 16:
+ d.err = d.writeStoredBlock(d.window[:d.windowEnd])
+ default:
+ d.w.writeBlockHuff(false, d.window[:d.windowEnd])
+ d.err = d.w.err
+ }
+ d.windowEnd = 0
+ d.bestSpeed.reset()
+ return
+ }
+
+ }
+ // Encode the block.
+ d.tokens = d.bestSpeed.encode(d.tokens[:0], d.window[:d.windowEnd])
+
+ // If we removed less than 1/16th, Huffman compress the block.
+ if len(d.tokens) > d.windowEnd-(d.windowEnd>>4) {
+ d.w.writeBlockHuff(false, d.window[:d.windowEnd])
+ } else {
+ d.w.writeBlockDynamic(d.tokens, false, d.window[:d.windowEnd])
+ }
+ d.err = d.w.err
+ d.windowEnd = 0
+}
+
+func (d *compressor) initDeflate() {
+ d.window = make([]byte, 2*windowSize)
+ d.hashOffset = 1
+ d.tokens = make([]token, 0, maxFlateBlockTokens+1)
+ d.length = minMatchLength - 1
+ d.offset = 0
+ d.byteAvailable = false
+ d.index = 0
+ d.chainHead = -1
+ d.bulkHasher = bulkHash4
+}
+
+func (d *compressor) deflate() {
+ if d.windowEnd-d.index < minMatchLength+maxMatchLength && !d.sync {
+ return
+ }
+
+ d.maxInsertIndex = d.windowEnd - (minMatchLength - 1)
+
+Loop:
+ for {
+ if d.index > d.windowEnd {
+ panic("index > windowEnd")
+ }
+ lookahead := d.windowEnd - d.index
+ if lookahead < minMatchLength+maxMatchLength {
+ if !d.sync {
+ break Loop
+ }
+ if d.index > d.windowEnd {
+ panic("index > windowEnd")
+ }
+ if lookahead == 0 {
+ // Flush current output block if any.
+ if d.byteAvailable {
+ // There is still one pending token that needs to be flushed
+ d.tokens = append(d.tokens, literalToken(uint32(d.window[d.index-1])))
+ d.byteAvailable = false
+ }
+ if len(d.tokens) > 0 {
+ if d.err = d.writeBlock(d.tokens, d.index); d.err != nil {
+ return
+ }
+ d.tokens = d.tokens[:0]
+ }
+ break Loop
+ }
+ }
+ if d.index < d.maxInsertIndex {
+ // Update the hash
+ hash := hash4(d.window[d.index : d.index+minMatchLength])
+ hh := &d.hashHead[hash&hashMask]
+ d.chainHead = int(*hh)
+ d.hashPrev[d.index&windowMask] = uint32(d.chainHead)
+ *hh = uint32(d.index + d.hashOffset)
+ }
+ prevLength := d.length
+ prevOffset := d.offset
+ d.length = minMatchLength - 1
+ d.offset = 0
+ minIndex := d.index - windowSize
+ if minIndex < 0 {
+ minIndex = 0
+ }
+
+ if d.chainHead-d.hashOffset >= minIndex &&
+ (d.fastSkipHashing != skipNever && lookahead > minMatchLength-1 ||
+ d.fastSkipHashing == skipNever && lookahead > prevLength && prevLength < d.lazy) {
+ if newLength, newOffset, ok := d.findMatch(d.index, d.chainHead-d.hashOffset, minMatchLength-1, lookahead); ok {
+ d.length = newLength
+ d.offset = newOffset
+ }
+ }
+ if d.fastSkipHashing != skipNever && d.length >= minMatchLength ||
+ d.fastSkipHashing == skipNever && prevLength >= minMatchLength && d.length <= prevLength {
+ // There was a match at the previous step, and the current match is
+ // not better. Output the previous match.
+ if d.fastSkipHashing != skipNever {
+ d.tokens = append(d.tokens, matchToken(uint32(d.length-baseMatchLength), uint32(d.offset-baseMatchOffset)))
+ } else {
+ d.tokens = append(d.tokens, matchToken(uint32(prevLength-baseMatchLength), uint32(prevOffset-baseMatchOffset)))
+ }
+ // Insert in the hash table all strings up to the end of the match.
+ // index and index-1 are already inserted. If there is not enough
+ // lookahead, the last two strings are not inserted into the hash
+ // table.
+ if d.length <= d.fastSkipHashing {
+ var newIndex int
+ if d.fastSkipHashing != skipNever {
+ newIndex = d.index + d.length
+ } else {
+ newIndex = d.index + prevLength - 1
+ }
+ index := d.index
+ for index++; index < newIndex; index++ {
+ if index < d.maxInsertIndex {
+ hash := hash4(d.window[index : index+minMatchLength])
+ // Get previous value with the same hash.
+ // Our chain should point to the previous value.
+ hh := &d.hashHead[hash&hashMask]
+ d.hashPrev[index&windowMask] = *hh
+ // Set the head of the hash chain to us.
+ *hh = uint32(index + d.hashOffset)
+ }
+ }
+ d.index = index
+
+ if d.fastSkipHashing == skipNever {
+ d.byteAvailable = false
+ d.length = minMatchLength - 1
+ }
+ } else {
+ // For matches this long, we don't bother inserting each individual
+ // item into the table.
+ d.index += d.length
+ }
+ if len(d.tokens) == maxFlateBlockTokens {
+ // The block includes the current character
+ if d.err = d.writeBlock(d.tokens, d.index); d.err != nil {
+ return
+ }
+ d.tokens = d.tokens[:0]
+ }
+ } else {
+ if d.fastSkipHashing != skipNever || d.byteAvailable {
+ i := d.index - 1
+ if d.fastSkipHashing != skipNever {
+ i = d.index
+ }
+ d.tokens = append(d.tokens, literalToken(uint32(d.window[i])))
+ if len(d.tokens) == maxFlateBlockTokens {
+ if d.err = d.writeBlock(d.tokens, i+1); d.err != nil {
+ return
+ }
+ d.tokens = d.tokens[:0]
+ }
+ }
+ d.index++
+ if d.fastSkipHashing == skipNever {
+ d.byteAvailable = true
+ }
+ }
+ }
+}
+
+func (d *compressor) fillStore(b []byte) int {
+ n := copy(d.window[d.windowEnd:], b)
+ d.windowEnd += n
+ return n
+}
+
+func (d *compressor) store() {
+ if d.windowEnd > 0 && (d.windowEnd == maxStoreBlockSize || d.sync) {
+ d.err = d.writeStoredBlock(d.window[:d.windowEnd])
+ d.windowEnd = 0
+ }
+}
+
+// storeHuff compresses and stores the currently added data
+// when the d.window is full or we are at the end of the stream.
+// Any error that occurred will be in d.err
+func (d *compressor) storeHuff() {
+ if d.windowEnd < len(d.window) && !d.sync || d.windowEnd == 0 {
+ return
+ }
+ d.w.writeBlockHuff(false, d.window[:d.windowEnd])
+ d.err = d.w.err
+ d.windowEnd = 0
+}
+
+func (d *compressor) write(b []byte) (n int, err error) {
+ if d.err != nil {
+ return 0, d.err
+ }
+ n = len(b)
+ for len(b) > 0 {
+ d.step(d)
+ b = b[d.fill(d, b):]
+ if d.err != nil {
+ return 0, d.err
+ }
+ }
+ return n, nil
+}
+
+func (d *compressor) syncFlush() error {
+ if d.err != nil {
+ return d.err
+ }
+ d.sync = true
+ d.step(d)
+ if d.err == nil {
+ d.w.writeStoredHeader(0, false)
+ d.w.flush()
+ d.err = d.w.err
+ }
+ d.sync = false
+ return d.err
+}
+
+func (d *compressor) init(w io.Writer, level int) (err error) {
+ d.w = newHuffmanBitWriter(w)
+
+ switch {
+ case level == NoCompression:
+ d.window = make([]byte, maxStoreBlockSize)
+ d.fill = (*compressor).fillStore
+ d.step = (*compressor).store
+ case level == HuffmanOnly:
+ d.window = make([]byte, maxStoreBlockSize)
+ d.fill = (*compressor).fillStore
+ d.step = (*compressor).storeHuff
+ case level == BestSpeed:
+ d.compressionLevel = levels[level]
+ d.window = make([]byte, maxStoreBlockSize)
+ d.fill = (*compressor).fillStore
+ d.step = (*compressor).encSpeed
+ d.bestSpeed = newDeflateFast()
+ d.tokens = make([]token, maxStoreBlockSize)
+ case level == DefaultCompression:
+ level = 6
+ fallthrough
+ case 2 <= level && level <= 9:
+ d.compressionLevel = levels[level]
+ d.initDeflate()
+ d.fill = (*compressor).fillDeflate
+ d.step = (*compressor).deflate
+ default:
+ return fmt.Errorf("flate: invalid compression level %d: want value in range [-2, 9]", level)
+ }
+ return nil
+}
+
+func (d *compressor) reset(w io.Writer) {
+ d.w.reset(w)
+ d.sync = false
+ d.err = nil
+ switch d.compressionLevel.level {
+ case NoCompression:
+ d.windowEnd = 0
+ case BestSpeed:
+ d.windowEnd = 0
+ d.tokens = d.tokens[:0]
+ d.bestSpeed.reset()
+ default:
+ d.chainHead = -1
+ for i := range d.hashHead {
+ d.hashHead[i] = 0
+ }
+ for i := range d.hashPrev {
+ d.hashPrev[i] = 0
+ }
+ d.hashOffset = 1
+ d.index, d.windowEnd = 0, 0
+ d.blockStart, d.byteAvailable = 0, false
+ d.tokens = d.tokens[:0]
+ d.length = minMatchLength - 1
+ d.offset = 0
+ d.maxInsertIndex = 0
+ }
+}
+
+func (d *compressor) close() error {
+ if d.err == errWriterClosed {
+ return nil
+ }
+ if d.err != nil {
+ return d.err
+ }
+ d.sync = true
+ d.step(d)
+ if d.err != nil {
+ return d.err
+ }
+ if d.w.writeStoredHeader(0, true); d.w.err != nil {
+ return d.w.err
+ }
+ d.w.flush()
+ if d.w.err != nil {
+ return d.w.err
+ }
+ d.err = errWriterClosed
+ return nil
+}
+
+// NewWriter returns a new Writer compressing data at the given level.
+// Following zlib, levels range from 1 (BestSpeed) to 9 (BestCompression);
+// higher levels typically run slower but compress more. Level 0
+// (NoCompression) does not attempt any compression; it only adds the
+// necessary DEFLATE framing.
+// Level -1 (DefaultCompression) uses the default compression level.
+// Level -2 (HuffmanOnly) will use Huffman compression only, giving
+// a very fast compression for all types of input, but sacrificing considerable
+// compression efficiency.
+//
+// If level is in the range [-2, 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) {
+ var dw Writer
+ if err := dw.d.init(w, level); err != nil {
+ return nil, err
+ }
+ return &dw, nil
+}
+
+// NewWriterDict is like NewWriter but initializes the new
+// Writer with a preset dictionary. The returned Writer behaves
+// as if the dictionary had been written to it without producing
+// any compressed output. The compressed data written to w
+// can only be decompressed by a Reader initialized with the
+// same dictionary.
+func NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) {
+ dw := &dictWriter{w}
+ zw, err := NewWriter(dw, level)
+ if err != nil {
+ return nil, err
+ }
+ zw.d.fillWindow(dict)
+ zw.dict = append(zw.dict, dict...) // duplicate dictionary for Reset method.
+ return zw, err
+}
+
+type dictWriter struct {
+ w io.Writer
+}
+
+func (w *dictWriter) Write(b []byte) (n int, err error) {
+ return w.w.Write(b)
+}
+
+var errWriterClosed = errors.New("flate: closed writer")
+
+// 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
+ dict []byte
+}
+
+// Write writes data to w, which will eventually write the
+// compressed form of data to its underlying writer.
+func (w *Writer) Write(data []byte) (n int, err error) {
+ return w.d.write(data)
+}
+
+// Flush flushes any pending data to the underlying writer.
+// It is useful mainly in compressed network protocols, to ensure that
+// a remote reader has enough data to reconstruct a packet.
+// Flush does not return until the data has been written.
+// Calling Flush when there is no pending data still causes the Writer
+// to emit a sync marker of at least 4 bytes.
+// If the underlying writer returns an error, Flush returns that error.
+//
+// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.
+func (w *Writer) Flush() error {
+ // For more about flushing:
+ // https://www.bolet.org/~pornin/deflate-flush.html
+ return w.d.syncFlush()
+}
+
+// Close flushes and closes the writer.
+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.writer.(*dictWriter); ok {
+ // w was created with NewWriterDict
+ dw.w = dst
+ w.d.reset(dw)
+ w.d.fillWindow(w.dict)
+ } else {
+ // w was created with NewWriter
+ w.d.reset(dst)
+ }
+}
diff --git a/src/compress/flate/deflate_test.go b/src/compress/flate/deflate_test.go
new file mode 100644
index 0000000..3610c7b
--- /dev/null
+++ b/src/compress/flate/deflate_test.go
@@ -0,0 +1,1070 @@
+// Copyright 2009 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 flate
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "internal/testenv"
+ "io"
+ "math/rand"
+ "os"
+ "reflect"
+ "runtime/debug"
+ "sync"
+ "testing"
+)
+
+type deflateTest struct {
+ in []byte
+ level int
+ out []byte
+}
+
+type deflateInflateTest struct {
+ in []byte
+}
+
+type reverseBitsTest struct {
+ in uint16
+ bitCount uint8
+ out uint16
+}
+
+var deflateTests = []*deflateTest{
+ {[]byte{}, 0, []byte{1, 0, 0, 255, 255}},
+ {[]byte{0x11}, -1, []byte{18, 4, 4, 0, 0, 255, 255}},
+ {[]byte{0x11}, DefaultCompression, []byte{18, 4, 4, 0, 0, 255, 255}},
+ {[]byte{0x11}, 4, []byte{18, 4, 4, 0, 0, 255, 255}},
+
+ {[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}},
+ {[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}},
+ {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0,
+ []byte{0, 8, 0, 247, 255, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0, 0, 255, 255},
+ },
+ {[]byte{}, 2, []byte{1, 0, 0, 255, 255}},
+ {[]byte{0x11}, 2, []byte{18, 4, 4, 0, 0, 255, 255}},
+ {[]byte{0x11, 0x12}, 2, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
+ {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 2, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}},
+ {[]byte{}, 9, []byte{1, 0, 0, 255, 255}},
+ {[]byte{0x11}, 9, []byte{18, 4, 4, 0, 0, 255, 255}},
+ {[]byte{0x11, 0x12}, 9, []byte{18, 20, 2, 4, 0, 0, 255, 255}},
+ {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 9, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}},
+}
+
+var deflateInflateTests = []*deflateInflateTest{
+ {[]byte{}},
+ {[]byte{0x11}},
+ {[]byte{0x11, 0x12}},
+ {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}},
+ {[]byte{0x11, 0x10, 0x13, 0x41, 0x21, 0x21, 0x41, 0x13, 0x87, 0x78, 0x13}},
+ {largeDataChunk()},
+}
+
+var reverseBitsTests = []*reverseBitsTest{
+ {1, 1, 1},
+ {1, 2, 2},
+ {1, 3, 4},
+ {1, 4, 8},
+ {1, 5, 16},
+ {17, 5, 17},
+ {257, 9, 257},
+ {29, 5, 23},
+}
+
+func largeDataChunk() []byte {
+ result := make([]byte, 100000)
+ for i := range result {
+ result[i] = byte(i * i & 0xFF)
+ }
+ return result
+}
+
+func TestBulkHash4(t *testing.T) {
+ for _, x := range deflateTests {
+ y := x.out
+ if len(y) < minMatchLength {
+ continue
+ }
+ y = append(y, y...)
+ for j := 4; j < len(y); j++ {
+ y := y[:j]
+ dst := make([]uint32, len(y)-minMatchLength+1)
+ for i := range dst {
+ dst[i] = uint32(i + 100)
+ }
+ bulkHash4(y, dst)
+ for i, got := range dst {
+ want := hash4(y[i:])
+ if got != want && got == uint32(i)+100 {
+ t.Errorf("Len:%d Index:%d, want 0x%08x but not modified", len(y), i, want)
+ } else if got != want {
+ t.Errorf("Len:%d Index:%d, got 0x%08x want:0x%08x", len(y), i, got, want)
+ }
+ }
+ }
+ }
+}
+
+func TestDeflate(t *testing.T) {
+ for _, h := range deflateTests {
+ var buf bytes.Buffer
+ w, err := NewWriter(&buf, h.level)
+ if err != nil {
+ t.Errorf("NewWriter: %v", err)
+ continue
+ }
+ w.Write(h.in)
+ w.Close()
+ if !bytes.Equal(buf.Bytes(), h.out) {
+ t.Errorf("Deflate(%d, %x) = \n%#v, want \n%#v", h.level, h.in, buf.Bytes(), h.out)
+ }
+ }
+}
+
+func TestWriterClose(t *testing.T) {
+ b := new(bytes.Buffer)
+ zw, err := NewWriter(b, 6)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+
+ if c, err := zw.Write([]byte("Test")); err != nil || c != 4 {
+ t.Fatalf("Write to not closed writer: %s, %d", err, c)
+ }
+
+ if err := zw.Close(); err != nil {
+ t.Fatalf("Close: %v", err)
+ }
+
+ afterClose := b.Len()
+
+ if c, err := zw.Write([]byte("Test")); err == nil || c != 0 {
+ t.Fatalf("Write to closed writer: %v, %d", err, c)
+ }
+
+ if err := zw.Flush(); err == nil {
+ t.Fatalf("Flush to closed writer: %s", err)
+ }
+
+ if err := zw.Close(); err != nil {
+ t.Fatalf("Close: %v", err)
+ }
+
+ if afterClose != b.Len() {
+ t.Fatalf("Writer wrote data after close. After close: %d. After writes on closed stream: %d", afterClose, b.Len())
+ }
+}
+
+// A sparseReader returns a stream consisting of 0s followed by 1<<16 1s.
+// This tests missing hash references in a very large input.
+type sparseReader struct {
+ l int64
+ cur int64
+}
+
+func (r *sparseReader) Read(b []byte) (n int, err error) {
+ if r.cur >= r.l {
+ return 0, io.EOF
+ }
+ n = len(b)
+ cur := r.cur + int64(n)
+ if cur > r.l {
+ n -= int(cur - r.l)
+ cur = r.l
+ }
+ for i := range b[0:n] {
+ if r.cur+int64(i) >= r.l-1<<16 {
+ b[i] = 1
+ } else {
+ b[i] = 0
+ }
+ }
+ r.cur = cur
+ return
+}
+
+func TestVeryLongSparseChunk(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping sparse chunk during short test")
+ }
+ w, err := NewWriter(io.Discard, 1)
+ if err != nil {
+ t.Errorf("NewWriter: %v", err)
+ return
+ }
+ if _, err = io.Copy(w, &sparseReader{l: 23e8}); err != nil {
+ t.Errorf("Compress failed: %v", err)
+ return
+ }
+}
+
+type syncBuffer struct {
+ buf bytes.Buffer
+ mu sync.RWMutex
+ closed bool
+ ready chan bool
+}
+
+func newSyncBuffer() *syncBuffer {
+ return &syncBuffer{ready: make(chan bool, 1)}
+}
+
+func (b *syncBuffer) Read(p []byte) (n int, err error) {
+ for {
+ b.mu.RLock()
+ n, err = b.buf.Read(p)
+ b.mu.RUnlock()
+ if n > 0 || b.closed {
+ return
+ }
+ <-b.ready
+ }
+}
+
+func (b *syncBuffer) signal() {
+ select {
+ case b.ready <- true:
+ default:
+ }
+}
+
+func (b *syncBuffer) Write(p []byte) (n int, err error) {
+ n, err = b.buf.Write(p)
+ b.signal()
+ return
+}
+
+func (b *syncBuffer) WriteMode() {
+ b.mu.Lock()
+}
+
+func (b *syncBuffer) ReadMode() {
+ b.mu.Unlock()
+ b.signal()
+}
+
+func (b *syncBuffer) Close() error {
+ b.closed = true
+ b.signal()
+ return nil
+}
+
+func testSync(t *testing.T, level int, input []byte, name string) {
+ if len(input) == 0 {
+ return
+ }
+
+ t.Logf("--testSync %d, %d, %s", level, len(input), name)
+ buf := newSyncBuffer()
+ buf1 := new(bytes.Buffer)
+ buf.WriteMode()
+ w, err := NewWriter(io.MultiWriter(buf, buf1), level)
+ if err != nil {
+ t.Errorf("NewWriter: %v", err)
+ return
+ }
+ r := NewReader(buf)
+
+ // Write half the input and read back.
+ for i := 0; i < 2; i++ {
+ var lo, hi int
+ if i == 0 {
+ lo, hi = 0, (len(input)+1)/2
+ } else {
+ lo, hi = (len(input)+1)/2, len(input)
+ }
+ t.Logf("#%d: write %d-%d", i, lo, hi)
+ if _, err := w.Write(input[lo:hi]); err != nil {
+ t.Errorf("testSync: write: %v", err)
+ return
+ }
+ if i == 0 {
+ if err := w.Flush(); err != nil {
+ t.Errorf("testSync: flush: %v", err)
+ return
+ }
+ } else {
+ if err := w.Close(); err != nil {
+ t.Errorf("testSync: close: %v", err)
+ }
+ }
+ buf.ReadMode()
+ out := make([]byte, hi-lo+1)
+ m, err := io.ReadAtLeast(r, out, hi-lo)
+ t.Logf("#%d: read %d", i, m)
+ if m != hi-lo || err != nil {
+ t.Errorf("testSync/%d (%d, %d, %s): read %d: %d, %v (%d left)", i, level, len(input), name, hi-lo, m, err, buf.buf.Len())
+ return
+ }
+ if !bytes.Equal(input[lo:hi], out[:hi-lo]) {
+ t.Errorf("testSync/%d: read wrong bytes: %x vs %x", i, input[lo:hi], out[:hi-lo])
+ return
+ }
+ // This test originally checked that after reading
+ // the first half of the input, there was nothing left
+ // in the read buffer (buf.buf.Len() != 0) but that is
+ // not necessarily the case: the write Flush may emit
+ // some extra framing bits that are not necessary
+ // to process to obtain the first half of the uncompressed
+ // data. The test ran correctly most of the time, because
+ // the background goroutine had usually read even
+ // those extra bits by now, but it's not a useful thing to
+ // check.
+ buf.WriteMode()
+ }
+ buf.ReadMode()
+ out := make([]byte, 10)
+ if n, err := r.Read(out); n > 0 || err != io.EOF {
+ t.Errorf("testSync (%d, %d, %s): final Read: %d, %v (hex: %x)", level, len(input), name, n, err, out[0:n])
+ }
+ if buf.buf.Len() != 0 {
+ t.Errorf("testSync (%d, %d, %s): extra data at end", level, len(input), name)
+ }
+ r.Close()
+
+ // stream should work for ordinary reader too
+ r = NewReader(buf1)
+ out, err = io.ReadAll(r)
+ if err != nil {
+ t.Errorf("testSync: read: %s", err)
+ return
+ }
+ r.Close()
+ if !bytes.Equal(input, out) {
+ t.Errorf("testSync: decompress(compress(data)) != data: level=%d input=%s", level, name)
+ }
+}
+
+func testToFromWithLevelAndLimit(t *testing.T, level int, input []byte, name string, limit int) {
+ var buffer bytes.Buffer
+ w, err := NewWriter(&buffer, level)
+ if err != nil {
+ t.Errorf("NewWriter: %v", err)
+ return
+ }
+ w.Write(input)
+ w.Close()
+ if limit > 0 && buffer.Len() > limit {
+ t.Errorf("level: %d, len(compress(data)) = %d > limit = %d", level, buffer.Len(), limit)
+ return
+ }
+ if limit > 0 {
+ t.Logf("level: %d, size:%.2f%%, %d b\n", level, float64(buffer.Len()*100)/float64(limit), buffer.Len())
+ }
+ r := NewReader(&buffer)
+ out, err := io.ReadAll(r)
+ if err != nil {
+ t.Errorf("read: %s", err)
+ return
+ }
+ r.Close()
+ if !bytes.Equal(input, out) {
+ t.Errorf("decompress(compress(data)) != data: level=%d input=%s", level, name)
+ return
+ }
+ testSync(t, level, input, name)
+}
+
+func testToFromWithLimit(t *testing.T, input []byte, name string, limit [11]int) {
+ for i := 0; i < 10; i++ {
+ testToFromWithLevelAndLimit(t, i, input, name, limit[i])
+ }
+ // Test HuffmanCompression
+ testToFromWithLevelAndLimit(t, -2, input, name, limit[10])
+}
+
+func TestDeflateInflate(t *testing.T) {
+ t.Parallel()
+ for i, h := range deflateInflateTests {
+ if testing.Short() && len(h.in) > 10000 {
+ continue
+ }
+ testToFromWithLimit(t, h.in, fmt.Sprintf("#%d", i), [11]int{})
+ }
+}
+
+func TestReverseBits(t *testing.T) {
+ for _, h := range reverseBitsTests {
+ if v := reverseBits(h.in, h.bitCount); v != h.out {
+ t.Errorf("reverseBits(%v,%v) = %v, want %v",
+ h.in, h.bitCount, v, h.out)
+ }
+ }
+}
+
+type deflateInflateStringTest struct {
+ filename string
+ label string
+ limit [11]int
+}
+
+var deflateInflateStringTests = []deflateInflateStringTest{
+ {
+ "../testdata/e.txt",
+ "2.718281828...",
+ [...]int{100018, 50650, 50960, 51150, 50930, 50790, 50790, 50790, 50790, 50790, 43683},
+ },
+ {
+ "../../testdata/Isaac.Newton-Opticks.txt",
+ "Isaac.Newton-Opticks",
+ [...]int{567248, 218338, 198211, 193152, 181100, 175427, 175427, 173597, 173422, 173422, 325240},
+ },
+}
+
+func TestDeflateInflateString(t *testing.T) {
+ t.Parallel()
+ if testing.Short() && testenv.Builder() == "" {
+ t.Skip("skipping in short mode")
+ }
+ for _, test := range deflateInflateStringTests {
+ gold, err := os.ReadFile(test.filename)
+ if err != nil {
+ t.Error(err)
+ }
+ testToFromWithLimit(t, gold, test.label, test.limit)
+ if testing.Short() {
+ break
+ }
+ }
+}
+
+func TestReaderDict(t *testing.T) {
+ const (
+ dict = "hello world"
+ text = "hello again world"
+ )
+ var b bytes.Buffer
+ w, err := NewWriter(&b, 5)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+ w.Write([]byte(dict))
+ w.Flush()
+ b.Reset()
+ w.Write([]byte(text))
+ w.Close()
+
+ r := NewReaderDict(&b, []byte(dict))
+ data, err := io.ReadAll(r)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if string(data) != "hello again world" {
+ t.Fatalf("read returned %q want %q", string(data), text)
+ }
+}
+
+func TestWriterDict(t *testing.T) {
+ const (
+ dict = "hello world"
+ text = "hello again world"
+ )
+ var b bytes.Buffer
+ w, err := NewWriter(&b, 5)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+ w.Write([]byte(dict))
+ w.Flush()
+ b.Reset()
+ w.Write([]byte(text))
+ w.Close()
+
+ var b1 bytes.Buffer
+ w, _ = NewWriterDict(&b1, 5, []byte(dict))
+ w.Write([]byte(text))
+ w.Close()
+
+ if !bytes.Equal(b1.Bytes(), b.Bytes()) {
+ t.Fatalf("writer wrote %q want %q", b1.Bytes(), b.Bytes())
+ }
+}
+
+// See https://golang.org/issue/2508
+func TestRegression2508(t *testing.T) {
+ if testing.Short() {
+ t.Logf("test disabled with -short")
+ return
+ }
+ w, err := NewWriter(io.Discard, 1)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+ buf := make([]byte, 1024)
+ for i := 0; i < 131072; i++ {
+ if _, err := w.Write(buf); err != nil {
+ t.Fatalf("writer failed: %v", err)
+ }
+ }
+ w.Close()
+}
+
+func TestWriterReset(t *testing.T) {
+ t.Parallel()
+ for level := 0; level <= 9; level++ {
+ if testing.Short() && level > 1 {
+ break
+ }
+ w, err := NewWriter(io.Discard, level)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+ buf := []byte("hello world")
+ n := 1024
+ if testing.Short() {
+ n = 10
+ }
+ for i := 0; i < n; i++ {
+ w.Write(buf)
+ }
+ w.Reset(io.Discard)
+
+ wref, err := NewWriter(io.Discard, level)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+
+ // DeepEqual doesn't compare functions.
+ w.d.fill, wref.d.fill = nil, nil
+ w.d.step, wref.d.step = nil, nil
+ w.d.bulkHasher, wref.d.bulkHasher = nil, nil
+ w.d.bestSpeed, wref.d.bestSpeed = nil, nil
+ // hashMatch is always overwritten when used.
+ copy(w.d.hashMatch[:], wref.d.hashMatch[:])
+ if len(w.d.tokens) != 0 {
+ t.Errorf("level %d Writer not reset after Reset. %d tokens were present", level, len(w.d.tokens))
+ }
+ // As long as the length is 0, we don't care about the content.
+ w.d.tokens = wref.d.tokens
+
+ // We don't care if there are values in the window, as long as it is at d.index is 0
+ w.d.window = wref.d.window
+ if !reflect.DeepEqual(w, wref) {
+ t.Errorf("level %d Writer not reset after Reset", level)
+ }
+ }
+
+ levels := []int{0, 1, 2, 5, 9}
+ for _, level := range levels {
+ t.Run(fmt.Sprint(level), func(t *testing.T) {
+ testResetOutput(t, level, nil)
+ })
+ }
+
+ t.Run("dict", func(t *testing.T) {
+ for _, level := range levels {
+ t.Run(fmt.Sprint(level), func(t *testing.T) {
+ testResetOutput(t, level, nil)
+ })
+ }
+ })
+}
+
+func testResetOutput(t *testing.T, level int, dict []byte) {
+ writeData := func(w *Writer) {
+ msg := []byte("now is the time for all good gophers")
+ w.Write(msg)
+ w.Flush()
+
+ hello := []byte("hello world")
+ for i := 0; i < 1024; i++ {
+ w.Write(hello)
+ }
+
+ fill := bytes.Repeat([]byte("x"), 65000)
+ w.Write(fill)
+ }
+
+ buf := new(bytes.Buffer)
+ var w *Writer
+ var err error
+ if dict == nil {
+ w, err = NewWriter(buf, level)
+ } else {
+ w, err = NewWriterDict(buf, level, dict)
+ }
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+
+ writeData(w)
+ w.Close()
+ out1 := buf.Bytes()
+
+ buf2 := new(bytes.Buffer)
+ w.Reset(buf2)
+ writeData(w)
+ w.Close()
+ out2 := buf2.Bytes()
+
+ if len(out1) != len(out2) {
+ t.Errorf("got %d, expected %d bytes", len(out2), len(out1))
+ return
+ }
+ if !bytes.Equal(out1, out2) {
+ mm := 0
+ for i, b := range out1[:len(out2)] {
+ if b != out2[i] {
+ t.Errorf("mismatch index %d: %#02x, expected %#02x", i, out2[i], b)
+ }
+ mm++
+ if mm == 10 {
+ t.Fatal("Stopping")
+ }
+ }
+ }
+ t.Logf("got %d bytes", len(out1))
+}
+
+// TestBestSpeed tests that round-tripping through deflate and then inflate
+// recovers the original input. The Write sizes are near the thresholds in the
+// compressor.encSpeed method (0, 16, 128), as well as near maxStoreBlockSize
+// (65535).
+func TestBestSpeed(t *testing.T) {
+ t.Parallel()
+ abc := make([]byte, 128)
+ for i := range abc {
+ abc[i] = byte(i)
+ }
+ abcabc := bytes.Repeat(abc, 131072/len(abc))
+ var want []byte
+
+ testCases := [][]int{
+ {65536, 0},
+ {65536, 1},
+ {65536, 1, 256},
+ {65536, 1, 65536},
+ {65536, 14},
+ {65536, 15},
+ {65536, 16},
+ {65536, 16, 256},
+ {65536, 16, 65536},
+ {65536, 127},
+ {65536, 128},
+ {65536, 128, 256},
+ {65536, 128, 65536},
+ {65536, 129},
+ {65536, 65536, 256},
+ {65536, 65536, 65536},
+ }
+
+ for i, tc := range testCases {
+ if i >= 3 && testing.Short() {
+ break
+ }
+ for _, firstN := range []int{1, 65534, 65535, 65536, 65537, 131072} {
+ tc[0] = firstN
+ outer:
+ for _, flush := range []bool{false, true} {
+ buf := new(bytes.Buffer)
+ want = want[:0]
+
+ w, err := NewWriter(buf, BestSpeed)
+ if err != nil {
+ t.Errorf("i=%d, firstN=%d, flush=%t: NewWriter: %v", i, firstN, flush, err)
+ continue
+ }
+ for _, n := range tc {
+ want = append(want, abcabc[:n]...)
+ if _, err := w.Write(abcabc[:n]); err != nil {
+ t.Errorf("i=%d, firstN=%d, flush=%t: Write: %v", i, firstN, flush, err)
+ continue outer
+ }
+ if !flush {
+ continue
+ }
+ if err := w.Flush(); err != nil {
+ t.Errorf("i=%d, firstN=%d, flush=%t: Flush: %v", i, firstN, flush, err)
+ continue outer
+ }
+ }
+ if err := w.Close(); err != nil {
+ t.Errorf("i=%d, firstN=%d, flush=%t: Close: %v", i, firstN, flush, err)
+ continue
+ }
+
+ r := NewReader(buf)
+ got, err := io.ReadAll(r)
+ if err != nil {
+ t.Errorf("i=%d, firstN=%d, flush=%t: ReadAll: %v", i, firstN, flush, err)
+ continue
+ }
+ r.Close()
+
+ if !bytes.Equal(got, want) {
+ t.Errorf("i=%d, firstN=%d, flush=%t: corruption during deflate-then-inflate", i, firstN, flush)
+ continue
+ }
+ }
+ }
+ }
+}
+
+var errIO = errors.New("IO error")
+
+// failWriter fails with errIO exactly at the nth call to Write.
+type failWriter struct{ n int }
+
+func (w *failWriter) Write(b []byte) (int, error) {
+ w.n--
+ if w.n == -1 {
+ return 0, errIO
+ }
+ return len(b), nil
+}
+
+func TestWriterPersistentWriteError(t *testing.T) {
+ t.Parallel()
+ d, err := os.ReadFile("../../testdata/Isaac.Newton-Opticks.txt")
+ if err != nil {
+ t.Fatalf("ReadFile: %v", err)
+ }
+ d = d[:10000] // Keep this test short
+
+ zw, err := NewWriter(nil, DefaultCompression)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+
+ // Sweep over the threshold at which an error is returned.
+ // The variable i makes it such that the ith call to failWriter.Write will
+ // return errIO. Since failWriter errors are not persistent, we must ensure
+ // that flate.Writer errors are persistent.
+ for i := 0; i < 1000; i++ {
+ fw := &failWriter{i}
+ zw.Reset(fw)
+
+ _, werr := zw.Write(d)
+ cerr := zw.Close()
+ ferr := zw.Flush()
+ if werr != errIO && werr != nil {
+ t.Errorf("test %d, mismatching Write error: got %v, want %v", i, werr, errIO)
+ }
+ if cerr != errIO && fw.n < 0 {
+ t.Errorf("test %d, mismatching Close error: got %v, want %v", i, cerr, errIO)
+ }
+ if ferr != errIO && fw.n < 0 {
+ t.Errorf("test %d, mismatching Flush error: got %v, want %v", i, ferr, errIO)
+ }
+ if fw.n >= 0 {
+ // At this point, the failure threshold was sufficiently high enough
+ // that we wrote the whole stream without any errors.
+ return
+ }
+ }
+}
+func TestWriterPersistentFlushError(t *testing.T) {
+ zw, err := NewWriter(&failWriter{0}, DefaultCompression)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+ flushErr := zw.Flush()
+ closeErr := zw.Close()
+ _, writeErr := zw.Write([]byte("Test"))
+ checkErrors([]error{closeErr, flushErr, writeErr}, errIO, t)
+}
+
+func TestWriterPersistentCloseError(t *testing.T) {
+ // If underlying writer return error on closing stream we should persistent this error across all writer calls.
+ zw, err := NewWriter(&failWriter{0}, DefaultCompression)
+ if err != nil {
+ t.Fatalf("NewWriter: %v", err)
+ }
+ closeErr := zw.Close()
+ flushErr := zw.Flush()
+ _, writeErr := zw.Write([]byte("Test"))
+ checkErrors([]error{closeErr, flushErr, writeErr}, errIO, t)
+
+ // After closing writer we should persistent "write after close" error across Flush and Write calls, but return nil
+ // on next Close calls.
+ var b bytes.Buffer
+ zw.Reset(&b)
+ err = zw.Close()
+ if err != nil {
+ t.Fatalf("First call to close returned error: %s", err)
+ }
+ err = zw.Close()
+ if err != nil {
+ t.Fatalf("Second call to close returned error: %s", err)
+ }
+
+ flushErr = zw.Flush()
+ _, writeErr = zw.Write([]byte("Test"))
+ checkErrors([]error{flushErr, writeErr}, errWriterClosed, t)
+}
+
+func checkErrors(got []error, want error, t *testing.T) {
+ t.Helper()
+ for _, err := range got {
+ if err != want {
+ t.Errorf("Error doesn't match\nWant: %s\nGot: %s", want, got)
+ }
+ }
+}
+
+func TestBestSpeedMatch(t *testing.T) {
+ t.Parallel()
+ cases := []struct {
+ previous, current []byte
+ t, s, want int32
+ }{{
+ previous: []byte{0, 0, 0, 1, 2},
+ current: []byte{3, 4, 5, 0, 1, 2, 3, 4, 5},
+ t: -3,
+ s: 3,
+ want: 6,
+ }, {
+ previous: []byte{0, 0, 0, 1, 2},
+ current: []byte{2, 4, 5, 0, 1, 2, 3, 4, 5},
+ t: -3,
+ s: 3,
+ want: 3,
+ }, {
+ previous: []byte{0, 0, 0, 1, 1},
+ current: []byte{3, 4, 5, 0, 1, 2, 3, 4, 5},
+ t: -3,
+ s: 3,
+ want: 2,
+ }, {
+ previous: []byte{0, 0, 0, 1, 2},
+ current: []byte{2, 2, 2, 2, 1, 2, 3, 4, 5},
+ t: -1,
+ s: 0,
+ want: 4,
+ }, {
+ previous: []byte{0, 0, 0, 1, 2, 3, 4, 5, 2, 2},
+ current: []byte{2, 2, 2, 2, 1, 2, 3, 4, 5},
+ t: -7,
+ s: 4,
+ want: 5,
+ }, {
+ previous: []byte{9, 9, 9, 9, 9},
+ current: []byte{2, 2, 2, 2, 1, 2, 3, 4, 5},
+ t: -1,
+ s: 0,
+ want: 0,
+ }, {
+ previous: []byte{9, 9, 9, 9, 9},
+ current: []byte{9, 2, 2, 2, 1, 2, 3, 4, 5},
+ t: 0,
+ s: 1,
+ want: 0,
+ }, {
+ previous: []byte{},
+ current: []byte{9, 2, 2, 2, 1, 2, 3, 4, 5},
+ t: -5,
+ s: 1,
+ want: 0,
+ }, {
+ previous: []byte{},
+ current: []byte{9, 2, 2, 2, 1, 2, 3, 4, 5},
+ t: -1,
+ s: 1,
+ want: 0,
+ }, {
+ previous: []byte{},
+ current: []byte{2, 2, 2, 2, 1, 2, 3, 4, 5},
+ t: 0,
+ s: 1,
+ want: 3,
+ }, {
+ previous: []byte{3, 4, 5},
+ current: []byte{3, 4, 5},
+ t: -3,
+ s: 0,
+ want: 3,
+ }, {
+ previous: make([]byte, 1000),
+ current: make([]byte, 1000),
+ t: -1000,
+ s: 0,
+ want: maxMatchLength - 4,
+ }, {
+ previous: make([]byte, 200),
+ current: make([]byte, 500),
+ t: -200,
+ s: 0,
+ want: maxMatchLength - 4,
+ }, {
+ previous: make([]byte, 200),
+ current: make([]byte, 500),
+ t: 0,
+ s: 1,
+ want: maxMatchLength - 4,
+ }, {
+ previous: make([]byte, maxMatchLength-4),
+ current: make([]byte, 500),
+ t: -(maxMatchLength - 4),
+ s: 0,
+ want: maxMatchLength - 4,
+ }, {
+ previous: make([]byte, 200),
+ current: make([]byte, 500),
+ t: -200,
+ s: 400,
+ want: 100,
+ }, {
+ previous: make([]byte, 10),
+ current: make([]byte, 500),
+ t: 200,
+ s: 400,
+ want: 100,
+ }}
+ for i, c := range cases {
+ e := deflateFast{prev: c.previous}
+ got := e.matchLen(c.s, c.t, c.current)
+ if got != c.want {
+ t.Errorf("Test %d: match length, want %d, got %d", i, c.want, got)
+ }
+ }
+}
+
+func TestBestSpeedMaxMatchOffset(t *testing.T) {
+ t.Parallel()
+ const abc, xyz = "abcdefgh", "stuvwxyz"
+ for _, matchBefore := range []bool{false, true} {
+ for _, extra := range []int{0, inputMargin - 1, inputMargin, inputMargin + 1, 2 * inputMargin} {
+ for offsetAdj := -5; offsetAdj <= +5; offsetAdj++ {
+ report := func(desc string, err error) {
+ t.Errorf("matchBefore=%t, extra=%d, offsetAdj=%d: %s%v",
+ matchBefore, extra, offsetAdj, desc, err)
+ }
+
+ offset := maxMatchOffset + offsetAdj
+
+ // Make src to be a []byte of the form
+ // "%s%s%s%s%s" % (abc, zeros0, xyzMaybe, abc, zeros1)
+ // where:
+ // zeros0 is approximately maxMatchOffset zeros.
+ // xyzMaybe is either xyz or the empty string.
+ // zeros1 is between 0 and 30 zeros.
+ // The difference between the two abc's will be offset, which
+ // is maxMatchOffset plus or minus a small adjustment.
+ src := make([]byte, offset+len(abc)+extra)
+ copy(src, abc)
+ if !matchBefore {
+ copy(src[offset-len(xyz):], xyz)
+ }
+ copy(src[offset:], abc)
+
+ buf := new(bytes.Buffer)
+ w, err := NewWriter(buf, BestSpeed)
+ if err != nil {
+ report("NewWriter: ", err)
+ continue
+ }
+ if _, err := w.Write(src); err != nil {
+ report("Write: ", err)
+ continue
+ }
+ if err := w.Close(); err != nil {
+ report("Writer.Close: ", err)
+ continue
+ }
+
+ r := NewReader(buf)
+ dst, err := io.ReadAll(r)
+ r.Close()
+ if err != nil {
+ report("ReadAll: ", err)
+ continue
+ }
+
+ if !bytes.Equal(dst, src) {
+ report("", fmt.Errorf("bytes differ after round-tripping"))
+ continue
+ }
+ }
+ }
+ }
+}
+
+func TestBestSpeedShiftOffsets(t *testing.T) {
+ // Test if shiftoffsets properly preserves matches and resets out-of-range matches
+ // seen in https://github.com/golang/go/issues/4142
+ enc := newDeflateFast()
+
+ // testData may not generate internal matches.
+ testData := make([]byte, 32)
+ rng := rand.New(rand.NewSource(0))
+ for i := range testData {
+ testData[i] = byte(rng.Uint32())
+ }
+
+ // Encode the testdata with clean state.
+ // Second part should pick up matches from the first block.
+ wantFirstTokens := len(enc.encode(nil, testData))
+ wantSecondTokens := len(enc.encode(nil, testData))
+
+ if wantFirstTokens <= wantSecondTokens {
+ t.Fatalf("test needs matches between inputs to be generated")
+ }
+ // Forward the current indicator to before wraparound.
+ enc.cur = bufferReset - int32(len(testData))
+
+ // Part 1 before wrap, should match clean state.
+ got := len(enc.encode(nil, testData))
+ if wantFirstTokens != got {
+ t.Errorf("got %d, want %d tokens", got, wantFirstTokens)
+ }
+
+ // Verify we are about to wrap.
+ if enc.cur != bufferReset {
+ t.Errorf("got %d, want e.cur to be at bufferReset (%d)", enc.cur, bufferReset)
+ }
+
+ // Part 2 should match clean state as well even if wrapped.
+ got = len(enc.encode(nil, testData))
+ if wantSecondTokens != got {
+ t.Errorf("got %d, want %d token", got, wantSecondTokens)
+ }
+
+ // Verify that we wrapped.
+ if enc.cur >= bufferReset {
+ t.Errorf("want e.cur to be < bufferReset (%d), got %d", bufferReset, enc.cur)
+ }
+
+ // Forward the current buffer, leaving the matches at the bottom.
+ enc.cur = bufferReset
+ enc.shiftOffsets()
+
+ // Ensure that no matches were picked up.
+ got = len(enc.encode(nil, testData))
+ if wantFirstTokens != got {
+ t.Errorf("got %d, want %d tokens", got, wantFirstTokens)
+ }
+}
+
+func TestMaxStackSize(t *testing.T) {
+ // This test must not run in parallel with other tests as debug.SetMaxStack
+ // affects all goroutines.
+ n := debug.SetMaxStack(1 << 16)
+ defer debug.SetMaxStack(n)
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ b := make([]byte, 1<<20)
+ for level := HuffmanOnly; level <= BestCompression; level++ {
+ // Run in separate goroutine to increase probability of stack regrowth.
+ wg.Add(1)
+ go func(level int) {
+ defer wg.Done()
+ zw, err := NewWriter(io.Discard, level)
+ if err != nil {
+ t.Errorf("level %d, NewWriter() = %v, want nil", level, err)
+ }
+ if n, err := zw.Write(b); n != len(b) || err != nil {
+ t.Errorf("level %d, Write() = (%d, %v), want (%d, nil)", level, n, err, len(b))
+ }
+ if err := zw.Close(); err != nil {
+ t.Errorf("level %d, Close() = %v, want nil", level, err)
+ }
+ zw.Reset(io.Discard)
+ }(level)
+ }
+}
diff --git a/src/compress/flate/deflatefast.go b/src/compress/flate/deflatefast.go
new file mode 100644
index 0000000..6aa439f
--- /dev/null
+++ b/src/compress/flate/deflatefast.go
@@ -0,0 +1,309 @@
+// Copyright 2016 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 flate
+
+import "math"
+
+// This encoding algorithm, which prioritizes speed over output size, is
+// based on Snappy's LZ77-style encoder: github.com/golang/snappy
+
+const (
+ tableBits = 14 // Bits used in the table.
+ tableSize = 1 << tableBits // Size of the table.
+ tableMask = tableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks.
+ tableShift = 32 - tableBits // Right-shift to get the tableBits most significant bits of a uint32.
+
+ // Reset the buffer offset when reaching this.
+ // Offsets are stored between blocks as int32 values.
+ // Since the offset we are checking against is at the beginning
+ // of the buffer, we need to subtract the current and input
+ // buffer to not risk overflowing the int32.
+ bufferReset = math.MaxInt32 - maxStoreBlockSize*2
+)
+
+func load32(b []byte, i int32) uint32 {
+ b = b[i : i+4 : len(b)] // Help the compiler eliminate bounds checks on the next line.
+ return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+}
+
+func load64(b []byte, i int32) uint64 {
+ b = b[i : i+8 : len(b)] // Help the compiler eliminate bounds checks on the next line.
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+}
+
+func hash(u uint32) uint32 {
+ return (u * 0x1e35a7bd) >> tableShift
+}
+
+// These constants are defined by the Snappy implementation so that its
+// assembly implementation can fast-path some 16-bytes-at-a-time copies. They
+// aren't necessary in the pure Go implementation, as we don't use those same
+// optimizations, but using the same thresholds doesn't really hurt.
+const (
+ inputMargin = 16 - 1
+ minNonLiteralBlockSize = 1 + 1 + inputMargin
+)
+
+type tableEntry struct {
+ val uint32 // Value at destination
+ offset int32
+}
+
+// deflateFast maintains the table for matches,
+// and the previous byte block for cross block matching.
+type deflateFast struct {
+ table [tableSize]tableEntry
+ prev []byte // Previous block, zero length if unknown.
+ cur int32 // Current match offset.
+}
+
+func newDeflateFast() *deflateFast {
+ return &deflateFast{cur: maxStoreBlockSize, prev: make([]byte, 0, maxStoreBlockSize)}
+}
+
+// encode encodes a block given in src and appends tokens
+// to dst and returns the result.
+func (e *deflateFast) encode(dst []token, src []byte) []token {
+ // Ensure that e.cur doesn't wrap.
+ if e.cur >= bufferReset {
+ e.shiftOffsets()
+ }
+
+ // This check isn't in the Snappy implementation, but there, the caller
+ // instead of the callee handles this case.
+ if len(src) < minNonLiteralBlockSize {
+ e.cur += maxStoreBlockSize
+ e.prev = e.prev[:0]
+ return emitLiteral(dst, src)
+ }
+
+ // sLimit is when to stop looking for offset/length copies. The inputMargin
+ // lets us use a fast path for emitLiteral in the main loop, while we are
+ // looking for copies.
+ sLimit := int32(len(src) - inputMargin)
+
+ // nextEmit is where in src the next emitLiteral should start from.
+ nextEmit := int32(0)
+ s := int32(0)
+ cv := load32(src, s)
+ nextHash := hash(cv)
+
+ for {
+ // Copied from the C++ snappy implementation:
+ //
+ // Heuristic match skipping: If 32 bytes are scanned with no matches
+ // found, start looking only at every other byte. If 32 more bytes are
+ // scanned (or skipped), look at every third byte, etc.. When a match
+ // is found, immediately go back to looking at every byte. This is a
+ // small loss (~5% performance, ~0.1% density) for compressible data
+ // due to more bookkeeping, but for non-compressible data (such as
+ // JPEG) it's a huge win since the compressor quickly "realizes" the
+ // data is incompressible and doesn't bother looking for matches
+ // everywhere.
+ //
+ // The "skip" variable keeps track of how many bytes there are since
+ // the last match; dividing it by 32 (ie. right-shifting by five) gives
+ // the number of bytes to move ahead for each iteration.
+ skip := int32(32)
+
+ nextS := s
+ var candidate tableEntry
+ for {
+ s = nextS
+ bytesBetweenHashLookups := skip >> 5
+ nextS = s + bytesBetweenHashLookups
+ skip += bytesBetweenHashLookups
+ if nextS > sLimit {
+ goto emitRemainder
+ }
+ candidate = e.table[nextHash&tableMask]
+ now := load32(src, nextS)
+ e.table[nextHash&tableMask] = tableEntry{offset: s + e.cur, val: cv}
+ nextHash = hash(now)
+
+ offset := s - (candidate.offset - e.cur)
+ if offset > maxMatchOffset || cv != candidate.val {
+ // Out of range or not matched.
+ cv = now
+ continue
+ }
+ break
+ }
+
+ // A 4-byte match has been found. We'll later see if more than 4 bytes
+ // match. But, prior to the match, src[nextEmit:s] are unmatched. Emit
+ // them as literal bytes.
+ dst = emitLiteral(dst, src[nextEmit:s])
+
+ // Call emitCopy, and then see if another emitCopy could be our next
+ // move. Repeat until we find no match for the input immediately after
+ // what was consumed by the last emitCopy call.
+ //
+ // If we exit this loop normally then we need to call emitLiteral next,
+ // though we don't yet know how big the literal will be. We handle that
+ // by proceeding to the next iteration of the main loop. We also can
+ // exit this loop via goto if we get close to exhausting the input.
+ for {
+ // Invariant: we have a 4-byte match at s, and no need to emit any
+ // literal bytes prior to s.
+
+ // Extend the 4-byte match as long as possible.
+ //
+ s += 4
+ t := candidate.offset - e.cur + 4
+ l := e.matchLen(s, t, src)
+
+ // matchToken is flate's equivalent of Snappy's emitCopy. (length,offset)
+ dst = append(dst, matchToken(uint32(l+4-baseMatchLength), uint32(s-t-baseMatchOffset)))
+ s += l
+ nextEmit = s
+ if s >= sLimit {
+ goto emitRemainder
+ }
+
+ // We could immediately start working at s now, but to improve
+ // compression we first update the hash table at s-1 and at s. If
+ // another emitCopy is not our next move, also calculate nextHash
+ // at s+1. At least on GOARCH=amd64, these three hash calculations
+ // are faster as one load64 call (with some shifts) instead of
+ // three load32 calls.
+ x := load64(src, s-1)
+ prevHash := hash(uint32(x))
+ e.table[prevHash&tableMask] = tableEntry{offset: e.cur + s - 1, val: uint32(x)}
+ x >>= 8
+ currHash := hash(uint32(x))
+ candidate = e.table[currHash&tableMask]
+ e.table[currHash&tableMask] = tableEntry{offset: e.cur + s, val: uint32(x)}
+
+ offset := s - (candidate.offset - e.cur)
+ if offset > maxMatchOffset || uint32(x) != candidate.val {
+ cv = uint32(x >> 8)
+ nextHash = hash(cv)
+ s++
+ break
+ }
+ }
+ }
+
+emitRemainder:
+ if int(nextEmit) < len(src) {
+ dst = emitLiteral(dst, src[nextEmit:])
+ }
+ e.cur += int32(len(src))
+ e.prev = e.prev[:len(src)]
+ copy(e.prev, src)
+ return dst
+}
+
+func emitLiteral(dst []token, lit []byte) []token {
+ for _, v := range lit {
+ dst = append(dst, literalToken(uint32(v)))
+ }
+ return dst
+}
+
+// matchLen returns the match length between src[s:] and src[t:].
+// t can be negative to indicate the match is starting in e.prev.
+// We assume that src[s-4:s] and src[t-4:t] already match.
+func (e *deflateFast) matchLen(s, t int32, src []byte) int32 {
+ s1 := int(s) + maxMatchLength - 4
+ if s1 > len(src) {
+ s1 = len(src)
+ }
+
+ // If we are inside the current block
+ if t >= 0 {
+ b := src[t:]
+ a := src[s:s1]
+ b = b[:len(a)]
+ // Extend the match to be as long as possible.
+ for i := range a {
+ if a[i] != b[i] {
+ return int32(i)
+ }
+ }
+ return int32(len(a))
+ }
+
+ // We found a match in the previous block.
+ tp := int32(len(e.prev)) + t
+ if tp < 0 {
+ return 0
+ }
+
+ // Extend the match to be as long as possible.
+ a := src[s:s1]
+ b := e.prev[tp:]
+ if len(b) > len(a) {
+ b = b[:len(a)]
+ }
+ a = a[:len(b)]
+ for i := range b {
+ if a[i] != b[i] {
+ return int32(i)
+ }
+ }
+
+ // If we reached our limit, we matched everything we are
+ // allowed to in the previous block and we return.
+ n := int32(len(b))
+ if int(s+n) == s1 {
+ return n
+ }
+
+ // Continue looking for more matches in the current block.
+ a = src[s+n : s1]
+ b = src[:len(a)]
+ for i := range a {
+ if a[i] != b[i] {
+ return int32(i) + n
+ }
+ }
+ return int32(len(a)) + n
+}
+
+// Reset resets the encoding history.
+// This ensures that no matches are made to the previous block.
+func (e *deflateFast) reset() {
+ e.prev = e.prev[:0]
+ // Bump the offset, so all matches will fail distance check.
+ // Nothing should be >= e.cur in the table.
+ e.cur += maxMatchOffset
+
+ // Protect against e.cur wraparound.
+ if e.cur >= bufferReset {
+ e.shiftOffsets()
+ }
+}
+
+// shiftOffsets will shift down all match offset.
+// This is only called in rare situations to prevent integer overflow.
+//
+// See https://golang.org/issue/18636 and https://github.com/golang/go/issues/34121.
+func (e *deflateFast) shiftOffsets() {
+ if len(e.prev) == 0 {
+ // We have no history; just clear the table.
+ for i := range e.table[:] {
+ e.table[i] = tableEntry{}
+ }
+ e.cur = maxMatchOffset + 1
+ return
+ }
+
+ // Shift down everything in the table that isn't already too far away.
+ for i := range e.table[:] {
+ v := e.table[i].offset - e.cur + maxMatchOffset + 1
+ if v < 0 {
+ // We want to reset e.cur to maxMatchOffset + 1, so we need to shift
+ // all table entries down by (e.cur - (maxMatchOffset + 1)).
+ // Because we ignore matches > maxMatchOffset, we can cap
+ // any negative offsets at 0.
+ v = 0
+ }
+ e.table[i].offset = v
+ }
+ e.cur = maxMatchOffset + 1
+}
diff --git a/src/compress/flate/dict_decoder.go b/src/compress/flate/dict_decoder.go
new file mode 100644
index 0000000..d2c1904
--- /dev/null
+++ b/src/compress/flate/dict_decoder.go
@@ -0,0 +1,182 @@
+// Copyright 2016 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 flate
+
+// dictDecoder implements the LZ77 sliding dictionary as used in decompression.
+// LZ77 decompresses data through sequences of two forms of commands:
+//
+// - Literal insertions: Runs of one or more symbols are inserted into the data
+// stream as is. This is accomplished through the writeByte method for a
+// single symbol, or combinations of writeSlice/writeMark for multiple symbols.
+// Any valid stream must start with a literal insertion if no preset dictionary
+// is used.
+//
+// - Backward copies: Runs of one or more symbols are copied from previously
+// emitted data. Backward copies come as the tuple (dist, length) where dist
+// determines how far back in the stream to copy from and length determines how
+// many bytes to copy. Note that it is valid for the length to be greater than
+// the distance. Since LZ77 uses forward copies, that situation is used to
+// perform a form of run-length encoding on repeated runs of symbols.
+// The writeCopy and tryWriteCopy are used to implement this command.
+//
+// For performance reasons, this implementation performs little to no sanity
+// checks about the arguments. As such, the invariants documented for each
+// method call must be respected.
+type dictDecoder struct {
+ hist []byte // Sliding window history
+
+ // Invariant: 0 <= rdPos <= wrPos <= len(hist)
+ wrPos int // Current output position in buffer
+ rdPos int // Have emitted hist[:rdPos] already
+ full bool // Has a full window length been written yet?
+}
+
+// init initializes dictDecoder to have a sliding window dictionary of the given
+// size. If a preset dict is provided, it will initialize the dictionary with
+// the contents of dict.
+func (dd *dictDecoder) init(size int, dict []byte) {
+ *dd = dictDecoder{hist: dd.hist}
+
+ if cap(dd.hist) < size {
+ dd.hist = make([]byte, size)
+ }
+ dd.hist = dd.hist[:size]
+
+ if len(dict) > len(dd.hist) {
+ dict = dict[len(dict)-len(dd.hist):]
+ }
+ dd.wrPos = copy(dd.hist, dict)
+ if dd.wrPos == len(dd.hist) {
+ dd.wrPos = 0
+ dd.full = true
+ }
+ dd.rdPos = dd.wrPos
+}
+
+// histSize reports the total amount of historical data in the dictionary.
+func (dd *dictDecoder) histSize() int {
+ if dd.full {
+ return len(dd.hist)
+ }
+ return dd.wrPos
+}
+
+// availRead reports the number of bytes that can be flushed by readFlush.
+func (dd *dictDecoder) availRead() int {
+ return dd.wrPos - dd.rdPos
+}
+
+// availWrite reports the available amount of output buffer space.
+func (dd *dictDecoder) availWrite() int {
+ return len(dd.hist) - dd.wrPos
+}
+
+// writeSlice returns a slice of the available buffer to write data to.
+//
+// This invariant will be kept: len(s) <= availWrite()
+func (dd *dictDecoder) writeSlice() []byte {
+ return dd.hist[dd.wrPos:]
+}
+
+// writeMark advances the writer pointer by cnt.
+//
+// This invariant must be kept: 0 <= cnt <= availWrite()
+func (dd *dictDecoder) writeMark(cnt int) {
+ dd.wrPos += cnt
+}
+
+// writeByte writes a single byte to the dictionary.
+//
+// This invariant must be kept: 0 < availWrite()
+func (dd *dictDecoder) writeByte(c byte) {
+ dd.hist[dd.wrPos] = c
+ dd.wrPos++
+}
+
+// writeCopy copies a string at a given (dist, length) to the output.
+// This returns the number of bytes copied and may be less than the requested
+// length if the available space in the output buffer is too small.
+//
+// This invariant must be kept: 0 < dist <= histSize()
+func (dd *dictDecoder) writeCopy(dist, length int) int {
+ dstBase := dd.wrPos
+ dstPos := dstBase
+ srcPos := dstPos - dist
+ endPos := dstPos + length
+ if endPos > len(dd.hist) {
+ endPos = len(dd.hist)
+ }
+
+ // Copy non-overlapping section after destination position.
+ //
+ // This section is non-overlapping in that the copy length for this section
+ // is always less than or equal to the backwards distance. This can occur
+ // if a distance refers to data that wraps-around in the buffer.
+ // Thus, a backwards copy is performed here; that is, the exact bytes in
+ // the source prior to the copy is placed in the destination.
+ if srcPos < 0 {
+ srcPos += len(dd.hist)
+ dstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:])
+ srcPos = 0
+ }
+
+ // Copy possibly overlapping section before destination position.
+ //
+ // This section can overlap if the copy length for this section is larger
+ // than the backwards distance. This is allowed by LZ77 so that repeated
+ // strings can be succinctly represented using (dist, length) pairs.
+ // Thus, a forwards copy is performed here; that is, the bytes copied is
+ // possibly dependent on the resulting bytes in the destination as the copy
+ // progresses along. This is functionally equivalent to the following:
+ //
+ // for i := 0; i < endPos-dstPos; i++ {
+ // dd.hist[dstPos+i] = dd.hist[srcPos+i]
+ // }
+ // dstPos = endPos
+ //
+ for dstPos < endPos {
+ dstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos])
+ }
+
+ dd.wrPos = dstPos
+ return dstPos - dstBase
+}
+
+// tryWriteCopy tries to copy a string at a given (distance, length) to the
+// output. This specialized version is optimized for short distances.
+//
+// This method is designed to be inlined for performance reasons.
+//
+// This invariant must be kept: 0 < dist <= histSize()
+func (dd *dictDecoder) tryWriteCopy(dist, length int) int {
+ dstPos := dd.wrPos
+ endPos := dstPos + length
+ if dstPos < dist || endPos > len(dd.hist) {
+ return 0
+ }
+ dstBase := dstPos
+ srcPos := dstPos - dist
+
+ // Copy possibly overlapping section before destination position.
+ for dstPos < endPos {
+ dstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos])
+ }
+
+ dd.wrPos = dstPos
+ return dstPos - dstBase
+}
+
+// readFlush returns a slice of the historical buffer that is ready to be
+// emitted to the user. The data returned by readFlush must be fully consumed
+// before calling any other dictDecoder methods.
+func (dd *dictDecoder) readFlush() []byte {
+ toRead := dd.hist[dd.rdPos:dd.wrPos]
+ dd.rdPos = dd.wrPos
+ if dd.wrPos == len(dd.hist) {
+ dd.wrPos, dd.rdPos = 0, 0
+ dd.full = true
+ }
+ return toRead
+}
diff --git a/src/compress/flate/dict_decoder_test.go b/src/compress/flate/dict_decoder_test.go
new file mode 100644
index 0000000..9275cff
--- /dev/null
+++ b/src/compress/flate/dict_decoder_test.go
@@ -0,0 +1,139 @@
+// Copyright 2016 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 flate
+
+import (
+ "bytes"
+ "strings"
+ "testing"
+)
+
+func TestDictDecoder(t *testing.T) {
+ const (
+ abc = "ABC\n"
+ fox = "The quick brown fox jumped over the lazy dog!\n"
+ poem = "The Road Not Taken\nRobert Frost\n" +
+ "\n" +
+ "Two roads diverged in a yellow wood,\n" +
+ "And sorry I could not travel both\n" +
+ "And be one traveler, long I stood\n" +
+ "And looked down one as far as I could\n" +
+ "To where it bent in the undergrowth;\n" +
+ "\n" +
+ "Then took the other, as just as fair,\n" +
+ "And having perhaps the better claim,\n" +
+ "Because it was grassy and wanted wear;\n" +
+ "Though as for that the passing there\n" +
+ "Had worn them really about the same,\n" +
+ "\n" +
+ "And both that morning equally lay\n" +
+ "In leaves no step had trodden black.\n" +
+ "Oh, I kept the first for another day!\n" +
+ "Yet knowing how way leads on to way,\n" +
+ "I doubted if I should ever come back.\n" +
+ "\n" +
+ "I shall be telling this with a sigh\n" +
+ "Somewhere ages and ages hence:\n" +
+ "Two roads diverged in a wood, and I-\n" +
+ "I took the one less traveled by,\n" +
+ "And that has made all the difference.\n"
+ )
+
+ var poemRefs = []struct {
+ dist int // Backward distance (0 if this is an insertion)
+ length int // Length of copy or insertion
+ }{
+ {0, 38}, {33, 3}, {0, 48}, {79, 3}, {0, 11}, {34, 5}, {0, 6}, {23, 7},
+ {0, 8}, {50, 3}, {0, 2}, {69, 3}, {34, 5}, {0, 4}, {97, 3}, {0, 4},
+ {43, 5}, {0, 6}, {7, 4}, {88, 7}, {0, 12}, {80, 3}, {0, 2}, {141, 4},
+ {0, 1}, {196, 3}, {0, 3}, {157, 3}, {0, 6}, {181, 3}, {0, 2}, {23, 3},
+ {77, 3}, {28, 5}, {128, 3}, {110, 4}, {70, 3}, {0, 4}, {85, 6}, {0, 2},
+ {182, 6}, {0, 4}, {133, 3}, {0, 7}, {47, 5}, {0, 20}, {112, 5}, {0, 1},
+ {58, 3}, {0, 8}, {59, 3}, {0, 4}, {173, 3}, {0, 5}, {114, 3}, {0, 4},
+ {92, 5}, {0, 2}, {71, 3}, {0, 2}, {76, 5}, {0, 1}, {46, 3}, {96, 4},
+ {130, 4}, {0, 3}, {360, 3}, {0, 3}, {178, 5}, {0, 7}, {75, 3}, {0, 3},
+ {45, 6}, {0, 6}, {299, 6}, {180, 3}, {70, 6}, {0, 1}, {48, 3}, {66, 4},
+ {0, 3}, {47, 5}, {0, 9}, {325, 3}, {0, 1}, {359, 3}, {318, 3}, {0, 2},
+ {199, 3}, {0, 1}, {344, 3}, {0, 3}, {248, 3}, {0, 10}, {310, 3}, {0, 3},
+ {93, 6}, {0, 3}, {252, 3}, {157, 4}, {0, 2}, {273, 5}, {0, 14}, {99, 4},
+ {0, 1}, {464, 4}, {0, 2}, {92, 4}, {495, 3}, {0, 1}, {322, 4}, {16, 4},
+ {0, 3}, {402, 3}, {0, 2}, {237, 4}, {0, 2}, {432, 4}, {0, 1}, {483, 5},
+ {0, 2}, {294, 4}, {0, 2}, {306, 3}, {113, 5}, {0, 1}, {26, 4}, {164, 3},
+ {488, 4}, {0, 1}, {542, 3}, {248, 6}, {0, 5}, {205, 3}, {0, 8}, {48, 3},
+ {449, 6}, {0, 2}, {192, 3}, {328, 4}, {9, 5}, {433, 3}, {0, 3}, {622, 25},
+ {615, 5}, {46, 5}, {0, 2}, {104, 3}, {475, 10}, {549, 3}, {0, 4}, {597, 8},
+ {314, 3}, {0, 1}, {473, 6}, {317, 5}, {0, 1}, {400, 3}, {0, 3}, {109, 3},
+ {151, 3}, {48, 4}, {0, 4}, {125, 3}, {108, 3}, {0, 2},
+ }
+
+ var got, want bytes.Buffer
+ var dd dictDecoder
+ dd.init(1<<11, nil)
+
+ var writeCopy = func(dist, length int) {
+ for length > 0 {
+ cnt := dd.tryWriteCopy(dist, length)
+ if cnt == 0 {
+ cnt = dd.writeCopy(dist, length)
+ }
+
+ length -= cnt
+ if dd.availWrite() == 0 {
+ got.Write(dd.readFlush())
+ }
+ }
+ }
+ var writeString = func(str string) {
+ for len(str) > 0 {
+ cnt := copy(dd.writeSlice(), str)
+ str = str[cnt:]
+ dd.writeMark(cnt)
+ if dd.availWrite() == 0 {
+ got.Write(dd.readFlush())
+ }
+ }
+ }
+
+ writeString(".")
+ want.WriteByte('.')
+
+ str := poem
+ for _, ref := range poemRefs {
+ if ref.dist == 0 {
+ writeString(str[:ref.length])
+ } else {
+ writeCopy(ref.dist, ref.length)
+ }
+ str = str[ref.length:]
+ }
+ want.WriteString(poem)
+
+ writeCopy(dd.histSize(), 33)
+ want.Write(want.Bytes()[:33])
+
+ writeString(abc)
+ writeCopy(len(abc), 59*len(abc))
+ want.WriteString(strings.Repeat(abc, 60))
+
+ writeString(fox)
+ writeCopy(len(fox), 9*len(fox))
+ want.WriteString(strings.Repeat(fox, 10))
+
+ writeString(".")
+ writeCopy(1, 9)
+ want.WriteString(strings.Repeat(".", 10))
+
+ writeString(strings.ToUpper(poem))
+ writeCopy(len(poem), 7*len(poem))
+ want.WriteString(strings.Repeat(strings.ToUpper(poem), 8))
+
+ writeCopy(dd.histSize(), 10)
+ want.Write(want.Bytes()[want.Len()-dd.histSize():][:10])
+
+ got.Write(dd.readFlush())
+ if got.String() != want.String() {
+ t.Errorf("final string mismatch:\ngot %q\nwant %q", got.String(), want.String())
+ }
+}
diff --git a/src/compress/flate/example_test.go b/src/compress/flate/example_test.go
new file mode 100644
index 0000000..5780092
--- /dev/null
+++ b/src/compress/flate/example_test.go
@@ -0,0 +1,243 @@
+// Copyright 2016 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 flate_test
+
+import (
+ "bytes"
+ "compress/flate"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "strings"
+ "sync"
+)
+
+// In performance critical applications, Reset can be used to discard the
+// current compressor or decompressor state and reinitialize them quickly
+// by taking advantage of previously allocated memory.
+func Example_reset() {
+ proverbs := []string{
+ "Don't communicate by sharing memory, share memory by communicating.\n",
+ "Concurrency is not parallelism.\n",
+ "The bigger the interface, the weaker the abstraction.\n",
+ "Documentation is for users.\n",
+ }
+
+ var r strings.Reader
+ var b bytes.Buffer
+ buf := make([]byte, 32<<10)
+
+ zw, err := flate.NewWriter(nil, flate.DefaultCompression)
+ if err != nil {
+ log.Fatal(err)
+ }
+ zr := flate.NewReader(nil)
+
+ for _, s := range proverbs {
+ r.Reset(s)
+ b.Reset()
+
+ // Reset the compressor and encode from some input stream.
+ zw.Reset(&b)
+ if _, err := io.CopyBuffer(zw, &r, buf); err != nil {
+ log.Fatal(err)
+ }
+ if err := zw.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ // Reset the decompressor and decode to some output stream.
+ if err := zr.(flate.Resetter).Reset(&b, nil); err != nil {
+ log.Fatal(err)
+ }
+ if _, err := io.CopyBuffer(os.Stdout, zr, buf); err != nil {
+ log.Fatal(err)
+ }
+ if err := zr.Close(); err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ // Output:
+ // Don't communicate by sharing memory, share memory by communicating.
+ // Concurrency is not parallelism.
+ // The bigger the interface, the weaker the abstraction.
+ // Documentation is for users.
+}
+
+// A preset dictionary can be used to improve the compression ratio.
+// The downside to using a dictionary is that the compressor and decompressor
+// must agree in advance what dictionary to use.
+func Example_dictionary() {
+ // The dictionary is a string of bytes. When compressing some input data,
+ // the compressor will attempt to substitute substrings with matches found
+ // in the dictionary. As such, the dictionary should only contain substrings
+ // that are expected to be found in the actual data stream.
+ const dict = `<?xml version="1.0"?>` + `<book>` + `<data>` + `<meta name="` + `" content="`
+
+ // The data to compress should (but is not required to) contain frequent
+ // substrings that match those in the dictionary.
+ const data = `<?xml version="1.0"?>
+<book>
+ <meta name="title" content="The Go Programming Language"/>
+ <meta name="authors" content="Alan Donovan and Brian Kernighan"/>
+ <meta name="published" content="2015-10-26"/>
+ <meta name="isbn" content="978-0134190440"/>
+ <data>...</data>
+</book>
+`
+
+ var b bytes.Buffer
+
+ // Compress the data using the specially crafted dictionary.
+ zw, err := flate.NewWriterDict(&b, flate.DefaultCompression, []byte(dict))
+ if err != nil {
+ log.Fatal(err)
+ }
+ if _, err := io.Copy(zw, strings.NewReader(data)); err != nil {
+ log.Fatal(err)
+ }
+ if err := zw.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ // The decompressor must use the same dictionary as the compressor.
+ // Otherwise, the input may appear as corrupted.
+ fmt.Println("Decompressed output using the dictionary:")
+ zr := flate.NewReaderDict(bytes.NewReader(b.Bytes()), []byte(dict))
+ if _, err := io.Copy(os.Stdout, zr); err != nil {
+ log.Fatal(err)
+ }
+ if err := zr.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println()
+
+ // Substitute all of the bytes in the dictionary with a '#' to visually
+ // demonstrate the approximate effectiveness of using a preset dictionary.
+ fmt.Println("Substrings matched by the dictionary are marked with #:")
+ hashDict := []byte(dict)
+ for i := range hashDict {
+ hashDict[i] = '#'
+ }
+ zr = flate.NewReaderDict(&b, hashDict)
+ if _, err := io.Copy(os.Stdout, zr); err != nil {
+ log.Fatal(err)
+ }
+ if err := zr.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // Decompressed output using the dictionary:
+ // <?xml version="1.0"?>
+ // <book>
+ // <meta name="title" content="The Go Programming Language"/>
+ // <meta name="authors" content="Alan Donovan and Brian Kernighan"/>
+ // <meta name="published" content="2015-10-26"/>
+ // <meta name="isbn" content="978-0134190440"/>
+ // <data>...</data>
+ // </book>
+ //
+ // Substrings matched by the dictionary are marked with #:
+ // #####################
+ // ######
+ // ############title###########The Go Programming Language"/#
+ // ############authors###########Alan Donovan and Brian Kernighan"/#
+ // ############published###########2015-10-26"/#
+ // ############isbn###########978-0134190440"/#
+ // ######...</#####
+ // </#####
+}
+
+// DEFLATE is suitable for transmitting compressed data across the network.
+func Example_synchronization() {
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ // Use io.Pipe to simulate a network connection.
+ // A real network application should take care to properly close the
+ // underlying connection.
+ rp, wp := io.Pipe()
+
+ // Start a goroutine to act as the transmitter.
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ zw, err := flate.NewWriter(wp, flate.BestSpeed)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ b := make([]byte, 256)
+ for _, m := range strings.Fields("A long time ago in a galaxy far, far away...") {
+ // We use a simple framing format where the first byte is the
+ // message length, followed the message itself.
+ b[0] = uint8(copy(b[1:], m))
+
+ if _, err := zw.Write(b[:1+len(m)]); err != nil {
+ log.Fatal(err)
+ }
+
+ // Flush ensures that the receiver can read all data sent so far.
+ if err := zw.Flush(); err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ if err := zw.Close(); err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ // Start a goroutine to act as the receiver.
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ zr := flate.NewReader(rp)
+
+ b := make([]byte, 256)
+ for {
+ // Read the message length.
+ // This is guaranteed to return for every corresponding
+ // Flush and Close on the transmitter side.
+ if _, err := io.ReadFull(zr, b[:1]); err != nil {
+ if err == io.EOF {
+ break // The transmitter closed the stream
+ }
+ log.Fatal(err)
+ }
+
+ // Read the message content.
+ n := int(b[0])
+ if _, err := io.ReadFull(zr, b[:n]); err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Printf("Received %d bytes: %s\n", n, b[:n])
+ }
+ fmt.Println()
+
+ if err := zr.Close(); err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ // Output:
+ // Received 1 bytes: A
+ // Received 4 bytes: long
+ // Received 4 bytes: time
+ // Received 3 bytes: ago
+ // Received 2 bytes: in
+ // Received 1 bytes: a
+ // Received 6 bytes: galaxy
+ // Received 4 bytes: far,
+ // Received 3 bytes: far
+ // Received 7 bytes: away...
+}
diff --git a/src/compress/flate/flate_test.go b/src/compress/flate/flate_test.go
new file mode 100644
index 0000000..23f4c47
--- /dev/null
+++ b/src/compress/flate/flate_test.go
@@ -0,0 +1,352 @@
+// Copyright 2009 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.
+
+// This test tests some internals of the flate package.
+// The tests in package compress/gzip serve as the
+// end-to-end test of the decompressor.
+
+package flate
+
+import (
+ "bytes"
+ "encoding/hex"
+ "io"
+ "strings"
+ "testing"
+)
+
+// The following test should not panic.
+func TestIssue5915(t *testing.T) {
+ bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0, 5, 5, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 6, 0, 11, 0, 8, 0, 6, 6, 10, 8}
+ var h huffmanDecoder
+ if h.init(bits) {
+ t.Fatalf("Given sequence of bits is bad, and should not succeed.")
+ }
+}
+
+// The following test should not panic.
+func TestIssue5962(t *testing.T) {
+ bits := []int{4, 0, 0, 6, 4, 3, 2, 3, 3, 4, 4, 5, 0, 0, 0, 0,
+ 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11}
+ var h huffmanDecoder
+ if h.init(bits) {
+ t.Fatalf("Given sequence of bits is bad, and should not succeed.")
+ }
+}
+
+// The following test should not panic.
+func TestIssue6255(t *testing.T) {
+ bits1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11}
+ bits2 := []int{11, 13}
+ var h huffmanDecoder
+ if !h.init(bits1) {
+ t.Fatalf("Given sequence of bits is good and should succeed.")
+ }
+ if h.init(bits2) {
+ t.Fatalf("Given sequence of bits is bad and should not succeed.")
+ }
+}
+
+func TestInvalidEncoding(t *testing.T) {
+ // Initialize Huffman decoder to recognize "0".
+ var h huffmanDecoder
+ if !h.init([]int{1}) {
+ t.Fatal("Failed to initialize Huffman decoder")
+ }
+
+ // Initialize decompressor with invalid Huffman coding.
+ var f decompressor
+ f.r = bytes.NewReader([]byte{0xff})
+
+ _, err := f.huffSym(&h)
+ if err == nil {
+ t.Fatal("Should have rejected invalid bit sequence")
+ }
+}
+
+func TestInvalidBits(t *testing.T) {
+ oversubscribed := []int{1, 2, 3, 4, 4, 5}
+ incomplete := []int{1, 2, 4, 4}
+ var h huffmanDecoder
+ if h.init(oversubscribed) {
+ t.Fatal("Should reject oversubscribed bit-length set")
+ }
+ if h.init(incomplete) {
+ t.Fatal("Should reject incomplete bit-length set")
+ }
+}
+
+func TestStreams(t *testing.T) {
+ // To verify any of these hexstrings as valid or invalid flate streams
+ // according to the C zlib library, you can use the Python wrapper library:
+ // >>> hex_string = "010100feff11"
+ // >>> import zlib
+ // >>> zlib.decompress(hex_string.decode("hex"), -15) # Negative means raw DEFLATE
+ // '\x11'
+
+ testCases := []struct {
+ desc string // Description of the stream
+ stream string // Hexstring of the input DEFLATE stream
+ want string // Expected result. Use "fail" to expect failure
+ }{{
+ "degenerate HCLenTree",
+ "05e0010000000000100000000000000000000000000000000000000000000000" +
+ "00000000000000000004",
+ "fail",
+ }, {
+ "complete HCLenTree, empty HLitTree, empty HDistTree",
+ "05e0010400000000000000000000000000000000000000000000000000000000" +
+ "00000000000000000010",
+ "fail",
+ }, {
+ "empty HCLenTree",
+ "05e0010000000000000000000000000000000000000000000000000000000000" +
+ "00000000000000000010",
+ "fail",
+ }, {
+ "complete HCLenTree, complete HLitTree, empty HDistTree, use missing HDist symbol",
+ "000100feff000de0010400000000100000000000000000000000000000000000" +
+ "0000000000000000000000000000002c",
+ "fail",
+ }, {
+ "complete HCLenTree, complete HLitTree, degenerate HDistTree, use missing HDist symbol",
+ "000100feff000de0010000000000000000000000000000000000000000000000" +
+ "00000000000000000610000000004070",
+ "fail",
+ }, {
+ "complete HCLenTree, empty HLitTree, empty HDistTree",
+ "05e0010400000000100400000000000000000000000000000000000000000000" +
+ "0000000000000000000000000008",
+ "fail",
+ }, {
+ "complete HCLenTree, empty HLitTree, degenerate HDistTree",
+ "05e0010400000000100400000000000000000000000000000000000000000000" +
+ "0000000000000000000800000008",
+ "fail",
+ }, {
+ "complete HCLenTree, degenerate HLitTree, degenerate HDistTree, use missing HLit symbol",
+ "05e0010400000000100000000000000000000000000000000000000000000000" +
+ "0000000000000000001c",
+ "fail",
+ }, {
+ "complete HCLenTree, complete HLitTree, too large HDistTree",
+ "edff870500000000200400000000000000000000000000000000000000000000" +
+ "000000000000000000080000000000000004",
+ "fail",
+ }, {
+ "complete HCLenTree, complete HLitTree, empty HDistTree, excessive repeater code",
+ "edfd870500000000200400000000000000000000000000000000000000000000" +
+ "000000000000000000e8b100",
+ "fail",
+ }, {
+ "complete HCLenTree, complete HLitTree, empty HDistTree of normal length 30",
+ "05fd01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
+ "ffffffffffffffffff07000000fe01",
+ "",
+ }, {
+ "complete HCLenTree, complete HLitTree, empty HDistTree of excessive length 31",
+ "05fe01240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
+ "ffffffffffffffffff07000000fc03",
+ "fail",
+ }, {
+ "complete HCLenTree, over-subscribed HLitTree, empty HDistTree",
+ "05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
+ "ffffffffffffffffff07f00f",
+ "fail",
+ }, {
+ "complete HCLenTree, under-subscribed HLitTree, empty HDistTree",
+ "05e001240000000000fcffffffffffffffffffffffffffffffffffffffffffff" +
+ "fffffffffcffffffff07f00f",
+ "fail",
+ }, {
+ "complete HCLenTree, complete HLitTree with single code, empty HDistTree",
+ "05e001240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
+ "ffffffffffffffffff07f00f",
+ "01",
+ }, {
+ "complete HCLenTree, complete HLitTree with multiple codes, empty HDistTree",
+ "05e301240000000000f8ffffffffffffffffffffffffffffffffffffffffffff" +
+ "ffffffffffffffffff07807f",
+ "01",
+ }, {
+ "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HDist symbol",
+ "000100feff000de0010400000000100000000000000000000000000000000000" +
+ "0000000000000000000000000000003c",
+ "00000000",
+ }, {
+ "complete HCLenTree, degenerate HLitTree, degenerate HDistTree",
+ "05e0010400000000100000000000000000000000000000000000000000000000" +
+ "0000000000000000000c",
+ "",
+ }, {
+ "complete HCLenTree, degenerate HLitTree, empty HDistTree",
+ "05e0010400000000100000000000000000000000000000000000000000000000" +
+ "00000000000000000004",
+ "",
+ }, {
+ "complete HCLenTree, complete HLitTree, empty HDistTree, spanning repeater code",
+ "edfd870500000000200400000000000000000000000000000000000000000000" +
+ "000000000000000000e8b000",
+ "",
+ }, {
+ "complete HCLenTree with length codes, complete HLitTree, empty HDistTree",
+ "ede0010400000000100000000000000000000000000000000000000000000000" +
+ "0000000000000000000400004000",
+ "",
+ }, {
+ "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit symbol 284 with count 31",
+ "000100feff00ede0010400000000100000000000000000000000000000000000" +
+ "000000000000000000000000000000040000407f00",
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "000000",
+ }, {
+ "complete HCLenTree, complete HLitTree, degenerate HDistTree, use valid HLit and HDist symbols",
+ "0cc2010d00000082b0ac4aff0eb07d27060000ffff",
+ "616263616263",
+ }, {
+ "fixed block, use reserved symbol 287",
+ "33180700",
+ "fail",
+ }, {
+ "raw block",
+ "010100feff11",
+ "11",
+ }, {
+ "issue 10426 - over-subscribed HCLenTree causes a hang",
+ "344c4a4e494d4b070000ff2e2eff2e2e2e2e2eff",
+ "fail",
+ }, {
+ "issue 11030 - empty HDistTree unexpectedly leads to error",
+ "05c0070600000080400fff37a0ca",
+ "",
+ }, {
+ "issue 11033 - empty HDistTree unexpectedly leads to error",
+ "050fb109c020cca5d017dcbca044881ee1034ec149c8980bbc413c2ab35be9dc" +
+ "b1473449922449922411202306ee97b0383a521b4ffdcf3217f9f7d3adb701",
+ "3130303634342068652e706870005d05355f7ed957ff084a90925d19e3ebc6d0" +
+ "c6d7",
+ }}
+
+ for i, tc := range testCases {
+ data, err := hex.DecodeString(tc.stream)
+ if err != nil {
+ t.Fatal(err)
+ }
+ data, err = io.ReadAll(NewReader(bytes.NewReader(data)))
+ if tc.want == "fail" {
+ if err == nil {
+ t.Errorf("#%d (%s): got nil error, want non-nil", i, tc.desc)
+ }
+ } else {
+ if err != nil {
+ t.Errorf("#%d (%s): %v", i, tc.desc, err)
+ continue
+ }
+ if got := hex.EncodeToString(data); got != tc.want {
+ t.Errorf("#%d (%s):\ngot %q\nwant %q", i, tc.desc, got, tc.want)
+ }
+
+ }
+ }
+}
+
+func TestTruncatedStreams(t *testing.T) {
+ const data = "\x00\f\x00\xf3\xffhello, world\x01\x00\x00\xff\xff"
+
+ for i := 0; i < len(data)-1; i++ {
+ r := NewReader(strings.NewReader(data[:i]))
+ _, err := io.Copy(io.Discard, r)
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("io.Copy(%d) on truncated stream: got %v, want %v", i, err, io.ErrUnexpectedEOF)
+ }
+ }
+}
+
+// Verify that flate.Reader.Read returns (n, io.EOF) instead
+// of (n, nil) + (0, io.EOF) when possible.
+//
+// This helps net/http.Transport reuse HTTP/1 connections more
+// aggressively.
+//
+// See https://github.com/google/go-github/pull/317 for background.
+func TestReaderEarlyEOF(t *testing.T) {
+ t.Parallel()
+ testSizes := []int{
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 100, 1000, 10000, 100000,
+ 128, 1024, 16384, 131072,
+
+ // Testing multiples of windowSize triggers the case
+ // where Read will fail to return an early io.EOF.
+ windowSize * 1, windowSize * 2, windowSize * 3,
+ }
+
+ var maxSize int
+ for _, n := range testSizes {
+ if maxSize < n {
+ maxSize = n
+ }
+ }
+
+ readBuf := make([]byte, 40)
+ data := make([]byte, maxSize)
+ for i := range data {
+ data[i] = byte(i)
+ }
+
+ for _, sz := range testSizes {
+ if testing.Short() && sz > windowSize {
+ continue
+ }
+ for _, flush := range []bool{true, false} {
+ earlyEOF := true // Do we expect early io.EOF?
+
+ var buf bytes.Buffer
+ w, _ := NewWriter(&buf, 5)
+ w.Write(data[:sz])
+ if flush {
+ // If a Flush occurs after all the actual data, the flushing
+ // semantics dictate that we will observe a (0, io.EOF) since
+ // Read must return data before it knows that the stream ended.
+ w.Flush()
+ earlyEOF = false
+ }
+ w.Close()
+
+ r := NewReader(&buf)
+ for {
+ n, err := r.Read(readBuf)
+ if err == io.EOF {
+ // If the availWrite == windowSize, then that means that the
+ // previous Read returned because the write buffer was full
+ // and it just so happened that the stream had no more data.
+ // This situation is rare, but unavoidable.
+ if r.(*decompressor).dict.availWrite() == windowSize {
+ earlyEOF = false
+ }
+
+ if n == 0 && earlyEOF {
+ t.Errorf("On size:%d flush:%v, Read() = (0, io.EOF), want (n, io.EOF)", sz, flush)
+ }
+ if n != 0 && !earlyEOF {
+ t.Errorf("On size:%d flush:%v, Read() = (%d, io.EOF), want (0, io.EOF)", sz, flush, n)
+ }
+ break
+ }
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+ }
+ }
+}
diff --git a/src/compress/flate/huffman_bit_writer.go b/src/compress/flate/huffman_bit_writer.go
new file mode 100644
index 0000000..0056375
--- /dev/null
+++ b/src/compress/flate/huffman_bit_writer.go
@@ -0,0 +1,701 @@
+// Copyright 2009 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 flate
+
+import (
+ "io"
+)
+
+const (
+ // The largest offset code.
+ offsetCodeCount = 30
+
+ // The special code used to mark the end of a block.
+ endBlockMarker = 256
+
+ // The first length code.
+ lengthCodesStart = 257
+
+ // The number of codegen codes.
+ codegenCodeCount = 19
+ badCode = 255
+
+ // bufferFlushSize indicates the buffer size
+ // after which bytes are flushed to the writer.
+ // Should preferably be a multiple of 6, since
+ // we accumulate 6 bytes between writes to the buffer.
+ bufferFlushSize = 240
+
+ // bufferSize is the actual output byte buffer size.
+ // It must have additional headroom for a flush
+ // which can contain up to 8 bytes.
+ bufferSize = bufferFlushSize + 8
+)
+
+// The number of extra bits needed by length code X - LENGTH_CODES_START.
+var lengthExtraBits = []int8{
+ /* 257 */ 0, 0, 0,
+ /* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,
+ /* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
+ /* 280 */ 4, 5, 5, 5, 5, 0,
+}
+
+// The length indicated by length code X - LENGTH_CODES_START.
+var lengthBase = []uint32{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10,
+ 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+ 64, 80, 96, 112, 128, 160, 192, 224, 255,
+}
+
+// offset code word extra bits.
+var offsetExtraBits = []int8{
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
+ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
+ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
+}
+
+var offsetBase = []uint32{
+ 0x000000, 0x000001, 0x000002, 0x000003, 0x000004,
+ 0x000006, 0x000008, 0x00000c, 0x000010, 0x000018,
+ 0x000020, 0x000030, 0x000040, 0x000060, 0x000080,
+ 0x0000c0, 0x000100, 0x000180, 0x000200, 0x000300,
+ 0x000400, 0x000600, 0x000800, 0x000c00, 0x001000,
+ 0x001800, 0x002000, 0x003000, 0x004000, 0x006000,
+}
+
+// The odd order in which the codegen code sizes are written.
+var codegenOrder = []uint32{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
+
+type huffmanBitWriter struct {
+ // writer is the underlying writer.
+ // Do not use it directly; use the write method, which ensures
+ // that Write errors are sticky.
+ writer io.Writer
+
+ // Data waiting to be written is bytes[0:nbytes]
+ // and then the low nbits of bits. Data is always written
+ // sequentially into the bytes array.
+ bits uint64
+ nbits uint
+ bytes [bufferSize]byte
+ codegenFreq [codegenCodeCount]int32
+ nbytes int
+ literalFreq []int32
+ offsetFreq []int32
+ codegen []uint8
+ literalEncoding *huffmanEncoder
+ offsetEncoding *huffmanEncoder
+ codegenEncoding *huffmanEncoder
+ err error
+}
+
+func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
+ return &huffmanBitWriter{
+ writer: w,
+ literalFreq: make([]int32, maxNumLit),
+ offsetFreq: make([]int32, offsetCodeCount),
+ codegen: make([]uint8, maxNumLit+offsetCodeCount+1),
+ literalEncoding: newHuffmanEncoder(maxNumLit),
+ codegenEncoding: newHuffmanEncoder(codegenCodeCount),
+ offsetEncoding: newHuffmanEncoder(offsetCodeCount),
+ }
+}
+
+func (w *huffmanBitWriter) reset(writer io.Writer) {
+ w.writer = writer
+ w.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil
+}
+
+func (w *huffmanBitWriter) flush() {
+ if w.err != nil {
+ w.nbits = 0
+ return
+ }
+ n := w.nbytes
+ for w.nbits != 0 {
+ w.bytes[n] = byte(w.bits)
+ w.bits >>= 8
+ if w.nbits > 8 { // Avoid underflow
+ w.nbits -= 8
+ } else {
+ w.nbits = 0
+ }
+ n++
+ }
+ w.bits = 0
+ w.write(w.bytes[:n])
+ w.nbytes = 0
+}
+
+func (w *huffmanBitWriter) write(b []byte) {
+ if w.err != nil {
+ return
+ }
+ _, w.err = w.writer.Write(b)
+}
+
+func (w *huffmanBitWriter) writeBits(b int32, nb uint) {
+ if w.err != nil {
+ return
+ }
+ w.bits |= uint64(b) << w.nbits
+ w.nbits += nb
+ if w.nbits >= 48 {
+ bits := w.bits
+ w.bits >>= 48
+ w.nbits -= 48
+ n := w.nbytes
+ bytes := w.bytes[n : n+6]
+ bytes[0] = byte(bits)
+ bytes[1] = byte(bits >> 8)
+ bytes[2] = byte(bits >> 16)
+ bytes[3] = byte(bits >> 24)
+ bytes[4] = byte(bits >> 32)
+ bytes[5] = byte(bits >> 40)
+ n += 6
+ if n >= bufferFlushSize {
+ w.write(w.bytes[:n])
+ n = 0
+ }
+ w.nbytes = n
+ }
+}
+
+func (w *huffmanBitWriter) writeBytes(bytes []byte) {
+ if w.err != nil {
+ return
+ }
+ n := w.nbytes
+ if w.nbits&7 != 0 {
+ w.err = InternalError("writeBytes with unfinished bits")
+ return
+ }
+ for w.nbits != 0 {
+ w.bytes[n] = byte(w.bits)
+ w.bits >>= 8
+ w.nbits -= 8
+ n++
+ }
+ if n != 0 {
+ w.write(w.bytes[:n])
+ }
+ w.nbytes = 0
+ w.write(bytes)
+}
+
+// RFC 1951 3.2.7 specifies a special run-length encoding for specifying
+// the literal and offset lengths arrays (which are concatenated into a single
+// array). This method generates that run-length encoding.
+//
+// The result is written into the codegen array, and the frequencies
+// of each code is written into the codegenFreq array.
+// Codes 0-15 are single byte codes. Codes 16-18 are followed by additional
+// information. Code badCode is an end marker
+//
+// numLiterals The number of literals in literalEncoding
+// numOffsets The number of offsets in offsetEncoding
+// litenc, offenc The literal and offset encoder to use
+func (w *huffmanBitWriter) generateCodegen(numLiterals int, numOffsets int, litEnc, offEnc *huffmanEncoder) {
+ for i := range w.codegenFreq {
+ w.codegenFreq[i] = 0
+ }
+ // Note that we are using codegen both as a temporary variable for holding
+ // a copy of the frequencies, and as the place where we put the result.
+ // This is fine because the output is always shorter than the input used
+ // so far.
+ codegen := w.codegen // cache
+ // Copy the concatenated code sizes to codegen. Put a marker at the end.
+ cgnl := codegen[:numLiterals]
+ for i := range cgnl {
+ cgnl[i] = uint8(litEnc.codes[i].len)
+ }
+
+ cgnl = codegen[numLiterals : numLiterals+numOffsets]
+ for i := range cgnl {
+ cgnl[i] = uint8(offEnc.codes[i].len)
+ }
+ codegen[numLiterals+numOffsets] = badCode
+
+ size := codegen[0]
+ count := 1
+ outIndex := 0
+ for inIndex := 1; size != badCode; inIndex++ {
+ // INVARIANT: We have seen "count" copies of size that have not yet
+ // had output generated for them.
+ nextSize := codegen[inIndex]
+ if nextSize == size {
+ count++
+ continue
+ }
+ // We need to generate codegen indicating "count" of size.
+ if size != 0 {
+ codegen[outIndex] = size
+ outIndex++
+ w.codegenFreq[size]++
+ count--
+ for count >= 3 {
+ n := 6
+ if n > count {
+ n = count
+ }
+ codegen[outIndex] = 16
+ outIndex++
+ codegen[outIndex] = uint8(n - 3)
+ outIndex++
+ w.codegenFreq[16]++
+ count -= n
+ }
+ } else {
+ for count >= 11 {
+ n := 138
+ if n > count {
+ n = count
+ }
+ codegen[outIndex] = 18
+ outIndex++
+ codegen[outIndex] = uint8(n - 11)
+ outIndex++
+ w.codegenFreq[18]++
+ count -= n
+ }
+ if count >= 3 {
+ // count >= 3 && count <= 10
+ codegen[outIndex] = 17
+ outIndex++
+ codegen[outIndex] = uint8(count - 3)
+ outIndex++
+ w.codegenFreq[17]++
+ count = 0
+ }
+ }
+ count--
+ for ; count >= 0; count-- {
+ codegen[outIndex] = size
+ outIndex++
+ w.codegenFreq[size]++
+ }
+ // Set up invariant for next time through the loop.
+ size = nextSize
+ count = 1
+ }
+ // Marker indicating the end of the codegen.
+ codegen[outIndex] = badCode
+}
+
+// dynamicSize returns the size of dynamically encoded data in bits.
+func (w *huffmanBitWriter) dynamicSize(litEnc, offEnc *huffmanEncoder, extraBits int) (size, numCodegens int) {
+ numCodegens = len(w.codegenFreq)
+ for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {
+ numCodegens--
+ }
+ header := 3 + 5 + 5 + 4 + (3 * numCodegens) +
+ w.codegenEncoding.bitLength(w.codegenFreq[:]) +
+ int(w.codegenFreq[16])*2 +
+ int(w.codegenFreq[17])*3 +
+ int(w.codegenFreq[18])*7
+ size = header +
+ litEnc.bitLength(w.literalFreq) +
+ offEnc.bitLength(w.offsetFreq) +
+ extraBits
+
+ return size, numCodegens
+}
+
+// fixedSize returns the size of dynamically encoded data in bits.
+func (w *huffmanBitWriter) fixedSize(extraBits int) int {
+ return 3 +
+ fixedLiteralEncoding.bitLength(w.literalFreq) +
+ fixedOffsetEncoding.bitLength(w.offsetFreq) +
+ extraBits
+}
+
+// storedSize calculates the stored size, including header.
+// The function returns the size in bits and whether the block
+// fits inside a single block.
+func (w *huffmanBitWriter) storedSize(in []byte) (int, bool) {
+ if in == nil {
+ return 0, false
+ }
+ if len(in) <= maxStoreBlockSize {
+ return (len(in) + 5) * 8, true
+ }
+ return 0, false
+}
+
+func (w *huffmanBitWriter) writeCode(c hcode) {
+ if w.err != nil {
+ return
+ }
+ w.bits |= uint64(c.code) << w.nbits
+ w.nbits += uint(c.len)
+ if w.nbits >= 48 {
+ bits := w.bits
+ w.bits >>= 48
+ w.nbits -= 48
+ n := w.nbytes
+ bytes := w.bytes[n : n+6]
+ bytes[0] = byte(bits)
+ bytes[1] = byte(bits >> 8)
+ bytes[2] = byte(bits >> 16)
+ bytes[3] = byte(bits >> 24)
+ bytes[4] = byte(bits >> 32)
+ bytes[5] = byte(bits >> 40)
+ n += 6
+ if n >= bufferFlushSize {
+ w.write(w.bytes[:n])
+ n = 0
+ }
+ w.nbytes = n
+ }
+}
+
+// Write the header of a dynamic Huffman block to the output stream.
+//
+// numLiterals The number of literals specified in codegen
+// numOffsets The number of offsets specified in codegen
+// numCodegens The number of codegens used in codegen
+func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, numCodegens int, isEof bool) {
+ if w.err != nil {
+ return
+ }
+ var firstBits int32 = 4
+ if isEof {
+ firstBits = 5
+ }
+ w.writeBits(firstBits, 3)
+ w.writeBits(int32(numLiterals-257), 5)
+ w.writeBits(int32(numOffsets-1), 5)
+ w.writeBits(int32(numCodegens-4), 4)
+
+ for i := 0; i < numCodegens; i++ {
+ value := uint(w.codegenEncoding.codes[codegenOrder[i]].len)
+ w.writeBits(int32(value), 3)
+ }
+
+ i := 0
+ for {
+ var codeWord int = int(w.codegen[i])
+ i++
+ if codeWord == badCode {
+ break
+ }
+ w.writeCode(w.codegenEncoding.codes[uint32(codeWord)])
+
+ switch codeWord {
+ case 16:
+ w.writeBits(int32(w.codegen[i]), 2)
+ i++
+ case 17:
+ w.writeBits(int32(w.codegen[i]), 3)
+ i++
+ case 18:
+ w.writeBits(int32(w.codegen[i]), 7)
+ i++
+ }
+ }
+}
+
+func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {
+ if w.err != nil {
+ return
+ }
+ var flag int32
+ if isEof {
+ flag = 1
+ }
+ w.writeBits(flag, 3)
+ w.flush()
+ w.writeBits(int32(length), 16)
+ w.writeBits(int32(^uint16(length)), 16)
+}
+
+func (w *huffmanBitWriter) writeFixedHeader(isEof bool) {
+ if w.err != nil {
+ return
+ }
+ // Indicate that we are a fixed Huffman block
+ var value int32 = 2
+ if isEof {
+ value = 3
+ }
+ w.writeBits(value, 3)
+}
+
+// writeBlock will write a block of tokens with the smallest encoding.
+// The original input can be supplied, and if the huffman encoded data
+// is larger than the original bytes, the data will be written as a
+// stored block.
+// If the input is nil, the tokens will always be Huffman encoded.
+func (w *huffmanBitWriter) writeBlock(tokens []token, eof bool, input []byte) {
+ if w.err != nil {
+ return
+ }
+
+ tokens = append(tokens, endBlockMarker)
+ numLiterals, numOffsets := w.indexTokens(tokens)
+
+ var extraBits int
+ storedSize, storable := w.storedSize(input)
+ if storable {
+ // We only bother calculating the costs of the extra bits required by
+ // the length of offset fields (which will be the same for both fixed
+ // and dynamic encoding), if we need to compare those two encodings
+ // against stored encoding.
+ for lengthCode := lengthCodesStart + 8; lengthCode < numLiterals; lengthCode++ {
+ // First eight length codes have extra size = 0.
+ extraBits += int(w.literalFreq[lengthCode]) * int(lengthExtraBits[lengthCode-lengthCodesStart])
+ }
+ for offsetCode := 4; offsetCode < numOffsets; offsetCode++ {
+ // First four offset codes have extra size = 0.
+ extraBits += int(w.offsetFreq[offsetCode]) * int(offsetExtraBits[offsetCode])
+ }
+ }
+
+ // Figure out smallest code.
+ // Fixed Huffman baseline.
+ var literalEncoding = fixedLiteralEncoding
+ var offsetEncoding = fixedOffsetEncoding
+ var size = w.fixedSize(extraBits)
+
+ // Dynamic Huffman?
+ var numCodegens int
+
+ // Generate codegen and codegenFrequencies, which indicates how to encode
+ // the literalEncoding and the offsetEncoding.
+ w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)
+ w.codegenEncoding.generate(w.codegenFreq[:], 7)
+ dynamicSize, numCodegens := w.dynamicSize(w.literalEncoding, w.offsetEncoding, extraBits)
+
+ if dynamicSize < size {
+ size = dynamicSize
+ literalEncoding = w.literalEncoding
+ offsetEncoding = w.offsetEncoding
+ }
+
+ // Stored bytes?
+ if storable && storedSize < size {
+ w.writeStoredHeader(len(input), eof)
+ w.writeBytes(input)
+ return
+ }
+
+ // Huffman.
+ if literalEncoding == fixedLiteralEncoding {
+ w.writeFixedHeader(eof)
+ } else {
+ w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)
+ }
+
+ // Write the tokens.
+ w.writeTokens(tokens, literalEncoding.codes, offsetEncoding.codes)
+}
+
+// writeBlockDynamic encodes a block using a dynamic Huffman table.
+// This should be used if the symbols used have a disproportionate
+// histogram distribution.
+// If input is supplied and the compression savings are below 1/16th of the
+// input size the block is stored.
+func (w *huffmanBitWriter) writeBlockDynamic(tokens []token, eof bool, input []byte) {
+ if w.err != nil {
+ return
+ }
+
+ tokens = append(tokens, endBlockMarker)
+ numLiterals, numOffsets := w.indexTokens(tokens)
+
+ // Generate codegen and codegenFrequencies, which indicates how to encode
+ // the literalEncoding and the offsetEncoding.
+ w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)
+ w.codegenEncoding.generate(w.codegenFreq[:], 7)
+ size, numCodegens := w.dynamicSize(w.literalEncoding, w.offsetEncoding, 0)
+
+ // Store bytes, if we don't get a reasonable improvement.
+ if ssize, storable := w.storedSize(input); storable && ssize < (size+size>>4) {
+ w.writeStoredHeader(len(input), eof)
+ w.writeBytes(input)
+ return
+ }
+
+ // Write Huffman table.
+ w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)
+
+ // Write the tokens.
+ w.writeTokens(tokens, w.literalEncoding.codes, w.offsetEncoding.codes)
+}
+
+// indexTokens indexes a slice of tokens, and updates
+// literalFreq and offsetFreq, and generates literalEncoding
+// and offsetEncoding.
+// The number of literal and offset tokens is returned.
+func (w *huffmanBitWriter) indexTokens(tokens []token) (numLiterals, numOffsets int) {
+ for i := range w.literalFreq {
+ w.literalFreq[i] = 0
+ }
+ for i := range w.offsetFreq {
+ w.offsetFreq[i] = 0
+ }
+
+ for _, t := range tokens {
+ if t < matchType {
+ w.literalFreq[t.literal()]++
+ continue
+ }
+ length := t.length()
+ offset := t.offset()
+ w.literalFreq[lengthCodesStart+lengthCode(length)]++
+ w.offsetFreq[offsetCode(offset)]++
+ }
+
+ // get the number of literals
+ numLiterals = len(w.literalFreq)
+ for w.literalFreq[numLiterals-1] == 0 {
+ numLiterals--
+ }
+ // get the number of offsets
+ numOffsets = len(w.offsetFreq)
+ for numOffsets > 0 && w.offsetFreq[numOffsets-1] == 0 {
+ numOffsets--
+ }
+ if numOffsets == 0 {
+ // We haven't found a single match. If we want to go with the dynamic encoding,
+ // we should count at least one offset to be sure that the offset huffman tree could be encoded.
+ w.offsetFreq[0] = 1
+ numOffsets = 1
+ }
+ w.literalEncoding.generate(w.literalFreq, 15)
+ w.offsetEncoding.generate(w.offsetFreq, 15)
+ return
+}
+
+// writeTokens writes a slice of tokens to the output.
+// codes for literal and offset encoding must be supplied.
+func (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode) {
+ if w.err != nil {
+ return
+ }
+ for _, t := range tokens {
+ if t < matchType {
+ w.writeCode(leCodes[t.literal()])
+ continue
+ }
+ // Write the length
+ length := t.length()
+ lengthCode := lengthCode(length)
+ w.writeCode(leCodes[lengthCode+lengthCodesStart])
+ extraLengthBits := uint(lengthExtraBits[lengthCode])
+ if extraLengthBits > 0 {
+ extraLength := int32(length - lengthBase[lengthCode])
+ w.writeBits(extraLength, extraLengthBits)
+ }
+ // Write the offset
+ offset := t.offset()
+ offsetCode := offsetCode(offset)
+ w.writeCode(oeCodes[offsetCode])
+ extraOffsetBits := uint(offsetExtraBits[offsetCode])
+ if extraOffsetBits > 0 {
+ extraOffset := int32(offset - offsetBase[offsetCode])
+ w.writeBits(extraOffset, extraOffsetBits)
+ }
+ }
+}
+
+// huffOffset is a static offset encoder used for huffman only encoding.
+// It can be reused since we will not be encoding offset values.
+var huffOffset *huffmanEncoder
+
+func init() {
+ offsetFreq := make([]int32, offsetCodeCount)
+ offsetFreq[0] = 1
+ huffOffset = newHuffmanEncoder(offsetCodeCount)
+ huffOffset.generate(offsetFreq, 15)
+}
+
+// writeBlockHuff encodes a block of bytes as either
+// Huffman encoded literals or uncompressed bytes if the
+// results only gains very little from compression.
+func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte) {
+ if w.err != nil {
+ return
+ }
+
+ // Clear histogram
+ for i := range w.literalFreq {
+ w.literalFreq[i] = 0
+ }
+
+ // Add everything as literals
+ histogram(input, w.literalFreq)
+
+ w.literalFreq[endBlockMarker] = 1
+
+ const numLiterals = endBlockMarker + 1
+ w.offsetFreq[0] = 1
+ const numOffsets = 1
+
+ w.literalEncoding.generate(w.literalFreq, 15)
+
+ // Figure out smallest code.
+ // Always use dynamic Huffman or Store
+ var numCodegens int
+
+ // Generate codegen and codegenFrequencies, which indicates how to encode
+ // the literalEncoding and the offsetEncoding.
+ w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, huffOffset)
+ w.codegenEncoding.generate(w.codegenFreq[:], 7)
+ size, numCodegens := w.dynamicSize(w.literalEncoding, huffOffset, 0)
+
+ // Store bytes, if we don't get a reasonable improvement.
+ if ssize, storable := w.storedSize(input); storable && ssize < (size+size>>4) {
+ w.writeStoredHeader(len(input), eof)
+ w.writeBytes(input)
+ return
+ }
+
+ // Huffman.
+ w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)
+ encoding := w.literalEncoding.codes[:257]
+ n := w.nbytes
+ for _, t := range input {
+ // Bitwriting inlined, ~30% speedup
+ c := encoding[t]
+ w.bits |= uint64(c.code) << w.nbits
+ w.nbits += uint(c.len)
+ if w.nbits < 48 {
+ continue
+ }
+ // Store 6 bytes
+ bits := w.bits
+ w.bits >>= 48
+ w.nbits -= 48
+ bytes := w.bytes[n : n+6]
+ bytes[0] = byte(bits)
+ bytes[1] = byte(bits >> 8)
+ bytes[2] = byte(bits >> 16)
+ bytes[3] = byte(bits >> 24)
+ bytes[4] = byte(bits >> 32)
+ bytes[5] = byte(bits >> 40)
+ n += 6
+ if n < bufferFlushSize {
+ continue
+ }
+ w.write(w.bytes[:n])
+ if w.err != nil {
+ return // Return early in the event of write failures
+ }
+ n = 0
+ }
+ w.nbytes = n
+ w.writeCode(encoding[endBlockMarker])
+}
+
+// histogram accumulates a histogram of b in h.
+//
+// len(h) must be >= 256, and h's elements must be all zeroes.
+func histogram(b []byte, h []int32) {
+ h = h[:256]
+ for _, t := range b {
+ h[t]++
+ }
+}
diff --git a/src/compress/flate/huffman_bit_writer_test.go b/src/compress/flate/huffman_bit_writer_test.go
new file mode 100644
index 0000000..a57799c
--- /dev/null
+++ b/src/compress/flate/huffman_bit_writer_test.go
@@ -0,0 +1,365 @@
+// Copyright 2016 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 flate
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+var update = flag.Bool("update", false, "update reference files")
+
+// TestBlockHuff tests huffman encoding against reference files
+// to detect possible regressions.
+// If encoding/bit allocation changes you can regenerate these files
+// by using the -update flag.
+func TestBlockHuff(t *testing.T) {
+ // determine input files
+ match, err := filepath.Glob("testdata/huffman-*.in")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ for _, in := range match {
+ out := in // for files where input and output are identical
+ if strings.HasSuffix(in, ".in") {
+ out = in[:len(in)-len(".in")] + ".golden"
+ }
+ testBlockHuff(t, in, out)
+ }
+}
+
+func testBlockHuff(t *testing.T, in, out string) {
+ all, err := os.ReadFile(in)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ var buf bytes.Buffer
+ bw := newHuffmanBitWriter(&buf)
+ bw.writeBlockHuff(false, all)
+ bw.flush()
+ got := buf.Bytes()
+
+ want, err := os.ReadFile(out)
+ if err != nil && !*update {
+ t.Error(err)
+ return
+ }
+
+ t.Logf("Testing %q", in)
+ if !bytes.Equal(got, want) {
+ if *update {
+ if in != out {
+ t.Logf("Updating %q", out)
+ if err := os.WriteFile(out, got, 0666); err != nil {
+ t.Error(err)
+ }
+ return
+ }
+ // in == out: don't accidentally destroy input
+ t.Errorf("WARNING: -update did not rewrite input file %s", in)
+ }
+
+ t.Errorf("%q != %q (see %q)", in, out, in+".got")
+ if err := os.WriteFile(in+".got", got, 0666); err != nil {
+ t.Error(err)
+ }
+ return
+ }
+ t.Log("Output ok")
+
+ // Test if the writer produces the same output after reset.
+ buf.Reset()
+ bw.reset(&buf)
+ bw.writeBlockHuff(false, all)
+ bw.flush()
+ got = buf.Bytes()
+ if !bytes.Equal(got, want) {
+ t.Errorf("after reset %q != %q (see %q)", in, out, in+".reset.got")
+ if err := os.WriteFile(in+".reset.got", got, 0666); err != nil {
+ t.Error(err)
+ }
+ return
+ }
+ t.Log("Reset ok")
+ testWriterEOF(t, "huff", huffTest{input: in}, true)
+}
+
+type huffTest struct {
+ tokens []token
+ input string // File name of input data matching the tokens.
+ want string // File name of data with the expected output with input available.
+ wantNoInput string // File name of the expected output when no input is available.
+}
+
+const ml = 0x7fc00000 // Maximum length token. Used to reduce the size of writeBlockTests
+
+var writeBlockTests = []huffTest{
+ {
+ input: "testdata/huffman-null-max.in",
+ want: "testdata/huffman-null-max.%s.expect",
+ wantNoInput: "testdata/huffman-null-max.%s.expect-noinput",
+ tokens: []token{0x0, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, 0x0, 0x0},
+ },
+ {
+ input: "testdata/huffman-pi.in",
+ want: "testdata/huffman-pi.%s.expect",
+ wantNoInput: "testdata/huffman-pi.%s.expect-noinput",
+ tokens: []token{0x33, 0x2e, 0x31, 0x34, 0x31, 0x35, 0x39, 0x32, 0x36, 0x35, 0x33, 0x35, 0x38, 0x39, 0x37, 0x39, 0x33, 0x32, 0x33, 0x38, 0x34, 0x36, 0x32, 0x36, 0x34, 0x33, 0x33, 0x38, 0x33, 0x32, 0x37, 0x39, 0x35, 0x30, 0x32, 0x38, 0x38, 0x34, 0x31, 0x39, 0x37, 0x31, 0x36, 0x39, 0x33, 0x39, 0x39, 0x33, 0x37, 0x35, 0x31, 0x30, 0x35, 0x38, 0x32, 0x30, 0x39, 0x37, 0x34, 0x39, 0x34, 0x34, 0x35, 0x39, 0x32, 0x33, 0x30, 0x37, 0x38, 0x31, 0x36, 0x34, 0x30, 0x36, 0x32, 0x38, 0x36, 0x32, 0x30, 0x38, 0x39, 0x39, 0x38, 0x36, 0x32, 0x38, 0x30, 0x33, 0x34, 0x38, 0x32, 0x35, 0x33, 0x34, 0x32, 0x31, 0x31, 0x37, 0x30, 0x36, 0x37, 0x39, 0x38, 0x32, 0x31, 0x34, 0x38, 0x30, 0x38, 0x36, 0x35, 0x31, 0x33, 0x32, 0x38, 0x32, 0x33, 0x30, 0x36, 0x36, 0x34, 0x37, 0x30, 0x39, 0x33, 0x38, 0x34, 0x34, 0x36, 0x30, 0x39, 0x35, 0x35, 0x30, 0x35, 0x38, 0x32, 0x32, 0x33, 0x31, 0x37, 0x32, 0x35, 0x33, 0x35, 0x39, 0x34, 0x30, 0x38, 0x31, 0x32, 0x38, 0x34, 0x38, 0x31, 0x31, 0x31, 0x37, 0x34, 0x4040007e, 0x34, 0x31, 0x30, 0x32, 0x37, 0x30, 0x31, 0x39, 0x33, 0x38, 0x35, 0x32, 0x31, 0x31, 0x30, 0x35, 0x35, 0x35, 0x39, 0x36, 0x34, 0x34, 0x36, 0x32, 0x32, 0x39, 0x34, 0x38, 0x39, 0x35, 0x34, 0x39, 0x33, 0x30, 0x33, 0x38, 0x31, 0x40400012, 0x32, 0x38, 0x38, 0x31, 0x30, 0x39, 0x37, 0x35, 0x36, 0x36, 0x35, 0x39, 0x33, 0x33, 0x34, 0x34, 0x36, 0x40400047, 0x37, 0x35, 0x36, 0x34, 0x38, 0x32, 0x33, 0x33, 0x37, 0x38, 0x36, 0x37, 0x38, 0x33, 0x31, 0x36, 0x35, 0x32, 0x37, 0x31, 0x32, 0x30, 0x31, 0x39, 0x30, 0x39, 0x31, 0x34, 0x4040001a, 0x35, 0x36, 0x36, 0x39, 0x32, 0x33, 0x34, 0x36, 0x404000b2, 0x36, 0x31, 0x30, 0x34, 0x35, 0x34, 0x33, 0x32, 0x36, 0x40400032, 0x31, 0x33, 0x33, 0x39, 0x33, 0x36, 0x30, 0x37, 0x32, 0x36, 0x30, 0x32, 0x34, 0x39, 0x31, 0x34, 0x31, 0x32, 0x37, 0x33, 0x37, 0x32, 0x34, 0x35, 0x38, 0x37, 0x30, 0x30, 0x36, 0x36, 0x30, 0x36, 0x33, 0x31, 0x35, 0x35, 0x38, 0x38, 0x31, 0x37, 0x34, 0x38, 0x38, 0x31, 0x35, 0x32, 0x30, 0x39, 0x32, 0x30, 0x39, 0x36, 0x32, 0x38, 0x32, 0x39, 0x32, 0x35, 0x34, 0x30, 0x39, 0x31, 0x37, 0x31, 0x35, 0x33, 0x36, 0x34, 0x33, 0x36, 0x37, 0x38, 0x39, 0x32, 0x35, 0x39, 0x30, 0x33, 0x36, 0x30, 0x30, 0x31, 0x31, 0x33, 0x33, 0x30, 0x35, 0x33, 0x30, 0x35, 0x34, 0x38, 0x38, 0x32, 0x30, 0x34, 0x36, 0x36, 0x35, 0x32, 0x31, 0x33, 0x38, 0x34, 0x31, 0x34, 0x36, 0x39, 0x35, 0x31, 0x39, 0x34, 0x31, 0x35, 0x31, 0x31, 0x36, 0x30, 0x39, 0x34, 0x33, 0x33, 0x30, 0x35, 0x37, 0x32, 0x37, 0x30, 0x33, 0x36, 0x35, 0x37, 0x35, 0x39, 0x35, 0x39, 0x31, 0x39, 0x35, 0x33, 0x30, 0x39, 0x32, 0x31, 0x38, 0x36, 0x31, 0x31, 0x37, 0x404000e9, 0x33, 0x32, 0x40400009, 0x39, 0x33, 0x31, 0x30, 0x35, 0x31, 0x31, 0x38, 0x35, 0x34, 0x38, 0x30, 0x37, 0x4040010e, 0x33, 0x37, 0x39, 0x39, 0x36, 0x32, 0x37, 0x34, 0x39, 0x35, 0x36, 0x37, 0x33, 0x35, 0x31, 0x38, 0x38, 0x35, 0x37, 0x35, 0x32, 0x37, 0x32, 0x34, 0x38, 0x39, 0x31, 0x32, 0x32, 0x37, 0x39, 0x33, 0x38, 0x31, 0x38, 0x33, 0x30, 0x31, 0x31, 0x39, 0x34, 0x39, 0x31, 0x32, 0x39, 0x38, 0x33, 0x33, 0x36, 0x37, 0x33, 0x33, 0x36, 0x32, 0x34, 0x34, 0x30, 0x36, 0x35, 0x36, 0x36, 0x34, 0x33, 0x30, 0x38, 0x36, 0x30, 0x32, 0x31, 0x33, 0x39, 0x34, 0x39, 0x34, 0x36, 0x33, 0x39, 0x35, 0x32, 0x32, 0x34, 0x37, 0x33, 0x37, 0x31, 0x39, 0x30, 0x37, 0x30, 0x32, 0x31, 0x37, 0x39, 0x38, 0x40800099, 0x37, 0x30, 0x32, 0x37, 0x37, 0x30, 0x35, 0x33, 0x39, 0x32, 0x31, 0x37, 0x31, 0x37, 0x36, 0x32, 0x39, 0x33, 0x31, 0x37, 0x36, 0x37, 0x35, 0x40800232, 0x37, 0x34, 0x38, 0x31, 0x40400006, 0x36, 0x36, 0x39, 0x34, 0x30, 0x404001e7, 0x30, 0x30, 0x30, 0x35, 0x36, 0x38, 0x31, 0x32, 0x37, 0x31, 0x34, 0x35, 0x32, 0x36, 0x33, 0x35, 0x36, 0x30, 0x38, 0x32, 0x37, 0x37, 0x38, 0x35, 0x37, 0x37, 0x31, 0x33, 0x34, 0x32, 0x37, 0x35, 0x37, 0x37, 0x38, 0x39, 0x36, 0x40400129, 0x33, 0x36, 0x33, 0x37, 0x31, 0x37, 0x38, 0x37, 0x32, 0x31, 0x34, 0x36, 0x38, 0x34, 0x34, 0x30, 0x39, 0x30, 0x31, 0x32, 0x32, 0x34, 0x39, 0x35, 0x33, 0x34, 0x33, 0x30, 0x31, 0x34, 0x36, 0x35, 0x34, 0x39, 0x35, 0x38, 0x35, 0x33, 0x37, 0x31, 0x30, 0x35, 0x30, 0x37, 0x39, 0x404000ca, 0x36, 0x40400153, 0x38, 0x39, 0x32, 0x33, 0x35, 0x34, 0x404001c9, 0x39, 0x35, 0x36, 0x31, 0x31, 0x32, 0x31, 0x32, 0x39, 0x30, 0x32, 0x31, 0x39, 0x36, 0x30, 0x38, 0x36, 0x34, 0x30, 0x33, 0x34, 0x34, 0x31, 0x38, 0x31, 0x35, 0x39, 0x38, 0x31, 0x33, 0x36, 0x32, 0x39, 0x37, 0x37, 0x34, 0x40400074, 0x30, 0x39, 0x39, 0x36, 0x30, 0x35, 0x31, 0x38, 0x37, 0x30, 0x37, 0x32, 0x31, 0x31, 0x33, 0x34, 0x39, 0x40800000, 0x38, 0x33, 0x37, 0x32, 0x39, 0x37, 0x38, 0x30, 0x34, 0x39, 0x39, 0x404002da, 0x39, 0x37, 0x33, 0x31, 0x37, 0x33, 0x32, 0x38, 0x4040018a, 0x36, 0x33, 0x31, 0x38, 0x35, 0x40400301, 0x404002e8, 0x34, 0x35, 0x35, 0x33, 0x34, 0x36, 0x39, 0x30, 0x38, 0x33, 0x30, 0x32, 0x36, 0x34, 0x32, 0x35, 0x32, 0x32, 0x33, 0x30, 0x404002e3, 0x40400267, 0x38, 0x35, 0x30, 0x33, 0x35, 0x32, 0x36, 0x31, 0x39, 0x33, 0x31, 0x31, 0x40400212, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x33, 0x31, 0x33, 0x37, 0x38, 0x33, 0x38, 0x37, 0x35, 0x32, 0x38, 0x38, 0x36, 0x35, 0x38, 0x37, 0x35, 0x33, 0x33, 0x32, 0x30, 0x38, 0x33, 0x38, 0x31, 0x34, 0x32, 0x30, 0x36, 0x40400140, 0x4040012b, 0x31, 0x34, 0x37, 0x33, 0x30, 0x33, 0x35, 0x39, 0x4080032e, 0x39, 0x30, 0x34, 0x32, 0x38, 0x37, 0x35, 0x35, 0x34, 0x36, 0x38, 0x37, 0x33, 0x31, 0x31, 0x35, 0x39, 0x35, 0x40400355, 0x33, 0x38, 0x38, 0x32, 0x33, 0x35, 0x33, 0x37, 0x38, 0x37, 0x35, 0x4080037f, 0x39, 0x4040013a, 0x31, 0x40400148, 0x38, 0x30, 0x35, 0x33, 0x4040018a, 0x32, 0x32, 0x36, 0x38, 0x30, 0x36, 0x36, 0x31, 0x33, 0x30, 0x30, 0x31, 0x39, 0x32, 0x37, 0x38, 0x37, 0x36, 0x36, 0x31, 0x31, 0x31, 0x39, 0x35, 0x39, 0x40400237, 0x36, 0x40800124, 0x38, 0x39, 0x33, 0x38, 0x30, 0x39, 0x35, 0x32, 0x35, 0x37, 0x32, 0x30, 0x31, 0x30, 0x36, 0x35, 0x34, 0x38, 0x35, 0x38, 0x36, 0x33, 0x32, 0x37, 0x4040009a, 0x39, 0x33, 0x36, 0x31, 0x35, 0x33, 0x40400220, 0x4080015c, 0x32, 0x33, 0x30, 0x33, 0x30, 0x31, 0x39, 0x35, 0x32, 0x30, 0x33, 0x35, 0x33, 0x30, 0x31, 0x38, 0x35, 0x32, 0x40400171, 0x40400075, 0x33, 0x36, 0x32, 0x32, 0x35, 0x39, 0x39, 0x34, 0x31, 0x33, 0x40400254, 0x34, 0x39, 0x37, 0x32, 0x31, 0x37, 0x404000de, 0x33, 0x34, 0x37, 0x39, 0x31, 0x33, 0x31, 0x35, 0x31, 0x35, 0x35, 0x37, 0x34, 0x38, 0x35, 0x37, 0x32, 0x34, 0x32, 0x34, 0x35, 0x34, 0x31, 0x35, 0x30, 0x36, 0x39, 0x4040013f, 0x38, 0x32, 0x39, 0x35, 0x33, 0x33, 0x31, 0x31, 0x36, 0x38, 0x36, 0x31, 0x37, 0x32, 0x37, 0x38, 0x40400337, 0x39, 0x30, 0x37, 0x35, 0x30, 0x39, 0x4040010d, 0x37, 0x35, 0x34, 0x36, 0x33, 0x37, 0x34, 0x36, 0x34, 0x39, 0x33, 0x39, 0x33, 0x31, 0x39, 0x32, 0x35, 0x35, 0x30, 0x36, 0x30, 0x34, 0x30, 0x30, 0x39, 0x4040026b, 0x31, 0x36, 0x37, 0x31, 0x31, 0x33, 0x39, 0x30, 0x30, 0x39, 0x38, 0x40400335, 0x34, 0x30, 0x31, 0x32, 0x38, 0x35, 0x38, 0x33, 0x36, 0x31, 0x36, 0x30, 0x33, 0x35, 0x36, 0x33, 0x37, 0x30, 0x37, 0x36, 0x36, 0x30, 0x31, 0x30, 0x34, 0x40400172, 0x38, 0x31, 0x39, 0x34, 0x32, 0x39, 0x4080041e, 0x404000ef, 0x4040028b, 0x37, 0x38, 0x33, 0x37, 0x34, 0x404004a8, 0x38, 0x32, 0x35, 0x35, 0x33, 0x37, 0x40800209, 0x32, 0x36, 0x38, 0x4040002e, 0x34, 0x30, 0x34, 0x37, 0x404001d1, 0x34, 0x404004b5, 0x4040038d, 0x38, 0x34, 0x404003a8, 0x36, 0x40c0031f, 0x33, 0x33, 0x31, 0x33, 0x36, 0x37, 0x37, 0x30, 0x32, 0x38, 0x39, 0x38, 0x39, 0x31, 0x35, 0x32, 0x40400062, 0x35, 0x32, 0x31, 0x36, 0x32, 0x30, 0x35, 0x36, 0x39, 0x36, 0x40400411, 0x30, 0x35, 0x38, 0x40400477, 0x35, 0x40400498, 0x35, 0x31, 0x31, 0x40400209, 0x38, 0x32, 0x34, 0x33, 0x30, 0x30, 0x33, 0x35, 0x35, 0x38, 0x37, 0x36, 0x34, 0x30, 0x32, 0x34, 0x37, 0x34, 0x39, 0x36, 0x34, 0x37, 0x33, 0x32, 0x36, 0x33, 0x4040043e, 0x39, 0x39, 0x32, 0x4040044b, 0x34, 0x32, 0x36, 0x39, 0x40c002c5, 0x37, 0x404001d6, 0x34, 0x4040053d, 0x4040041d, 0x39, 0x33, 0x34, 0x31, 0x37, 0x404001ad, 0x31, 0x32, 0x4040002a, 0x34, 0x4040019e, 0x31, 0x35, 0x30, 0x33, 0x30, 0x32, 0x38, 0x36, 0x31, 0x38, 0x32, 0x39, 0x37, 0x34, 0x35, 0x35, 0x35, 0x37, 0x30, 0x36, 0x37, 0x34, 0x40400135, 0x35, 0x30, 0x35, 0x34, 0x39, 0x34, 0x35, 0x38, 0x404001c5, 0x39, 0x40400051, 0x35, 0x36, 0x404001ec, 0x37, 0x32, 0x31, 0x30, 0x37, 0x39, 0x40400159, 0x33, 0x30, 0x4040010a, 0x33, 0x32, 0x31, 0x31, 0x36, 0x35, 0x33, 0x34, 0x34, 0x39, 0x38, 0x37, 0x32, 0x30, 0x32, 0x37, 0x4040011b, 0x30, 0x32, 0x33, 0x36, 0x34, 0x4040022e, 0x35, 0x34, 0x39, 0x39, 0x31, 0x31, 0x39, 0x38, 0x40400418, 0x34, 0x4040011b, 0x35, 0x33, 0x35, 0x36, 0x36, 0x33, 0x36, 0x39, 0x40400450, 0x32, 0x36, 0x35, 0x404002e4, 0x37, 0x38, 0x36, 0x32, 0x35, 0x35, 0x31, 0x404003da, 0x31, 0x37, 0x35, 0x37, 0x34, 0x36, 0x37, 0x32, 0x38, 0x39, 0x30, 0x39, 0x37, 0x37, 0x37, 0x37, 0x40800453, 0x30, 0x30, 0x30, 0x404005fd, 0x37, 0x30, 0x404004df, 0x36, 0x404003e9, 0x34, 0x39, 0x31, 0x4040041e, 0x40400297, 0x32, 0x31, 0x34, 0x37, 0x37, 0x32, 0x33, 0x35, 0x30, 0x31, 0x34, 0x31, 0x34, 0x40400643, 0x33, 0x35, 0x36, 0x404004af, 0x31, 0x36, 0x31, 0x33, 0x36, 0x31, 0x31, 0x35, 0x37, 0x33, 0x35, 0x32, 0x35, 0x40400504, 0x33, 0x34, 0x4040005b, 0x31, 0x38, 0x4040047b, 0x38, 0x34, 0x404005e7, 0x33, 0x33, 0x32, 0x33, 0x39, 0x30, 0x37, 0x33, 0x39, 0x34, 0x31, 0x34, 0x33, 0x33, 0x33, 0x34, 0x35, 0x34, 0x37, 0x37, 0x36, 0x32, 0x34, 0x40400242, 0x32, 0x35, 0x31, 0x38, 0x39, 0x38, 0x33, 0x35, 0x36, 0x39, 0x34, 0x38, 0x35, 0x35, 0x36, 0x32, 0x30, 0x39, 0x39, 0x32, 0x31, 0x39, 0x32, 0x32, 0x32, 0x31, 0x38, 0x34, 0x32, 0x37, 0x4040023e, 0x32, 0x404000ba, 0x36, 0x38, 0x38, 0x37, 0x36, 0x37, 0x31, 0x37, 0x39, 0x30, 0x40400055, 0x30, 0x40800106, 0x36, 0x36, 0x404003e7, 0x38, 0x38, 0x36, 0x32, 0x37, 0x32, 0x404006dc, 0x31, 0x37, 0x38, 0x36, 0x30, 0x38, 0x35, 0x37, 0x40400073, 0x33, 0x408002fc, 0x37, 0x39, 0x37, 0x36, 0x36, 0x38, 0x31, 0x404002bd, 0x30, 0x30, 0x39, 0x35, 0x33, 0x38, 0x38, 0x40400638, 0x33, 0x404006a5, 0x30, 0x36, 0x38, 0x30, 0x30, 0x36, 0x34, 0x32, 0x32, 0x35, 0x31, 0x32, 0x35, 0x32, 0x4040057b, 0x37, 0x33, 0x39, 0x32, 0x40400297, 0x40400474, 0x34, 0x408006b3, 0x38, 0x36, 0x32, 0x36, 0x39, 0x34, 0x35, 0x404001e5, 0x34, 0x31, 0x39, 0x36, 0x35, 0x32, 0x38, 0x35, 0x30, 0x40400099, 0x4040039c, 0x31, 0x38, 0x36, 0x33, 0x404001be, 0x34, 0x40800154, 0x32, 0x30, 0x33, 0x39, 0x4040058b, 0x34, 0x35, 0x404002bc, 0x32, 0x33, 0x37, 0x4040042c, 0x36, 0x40400510, 0x35, 0x36, 0x40400638, 0x37, 0x31, 0x39, 0x31, 0x37, 0x32, 0x38, 0x40400171, 0x37, 0x36, 0x34, 0x36, 0x35, 0x37, 0x35, 0x37, 0x33, 0x39, 0x40400101, 0x33, 0x38, 0x39, 0x40400748, 0x38, 0x33, 0x32, 0x36, 0x34, 0x35, 0x39, 0x39, 0x35, 0x38, 0x404006a7, 0x30, 0x34, 0x37, 0x38, 0x404001de, 0x40400328, 0x39, 0x4040002d, 0x36, 0x34, 0x30, 0x37, 0x38, 0x39, 0x35, 0x31, 0x4040008e, 0x36, 0x38, 0x33, 0x4040012f, 0x32, 0x35, 0x39, 0x35, 0x37, 0x30, 0x40400468, 0x38, 0x32, 0x32, 0x404002c8, 0x32, 0x4040061b, 0x34, 0x30, 0x37, 0x37, 0x32, 0x36, 0x37, 0x31, 0x39, 0x34, 0x37, 0x38, 0x40400319, 0x38, 0x32, 0x36, 0x30, 0x31, 0x34, 0x37, 0x36, 0x39, 0x39, 0x30, 0x39, 0x404004e8, 0x30, 0x31, 0x33, 0x36, 0x33, 0x39, 0x34, 0x34, 0x33, 0x4040027f, 0x33, 0x30, 0x40400105, 0x32, 0x30, 0x33, 0x34, 0x39, 0x36, 0x32, 0x35, 0x32, 0x34, 0x35, 0x31, 0x37, 0x404003b5, 0x39, 0x36, 0x35, 0x31, 0x34, 0x33, 0x31, 0x34, 0x32, 0x39, 0x38, 0x30, 0x39, 0x31, 0x39, 0x30, 0x36, 0x35, 0x39, 0x32, 0x40400282, 0x37, 0x32, 0x32, 0x31, 0x36, 0x39, 0x36, 0x34, 0x36, 0x40400419, 0x4040007a, 0x35, 0x4040050e, 0x34, 0x40800565, 0x38, 0x40400559, 0x39, 0x37, 0x4040057b, 0x35, 0x34, 0x4040049d, 0x4040023e, 0x37, 0x4040065a, 0x38, 0x34, 0x36, 0x38, 0x31, 0x33, 0x4040008c, 0x36, 0x38, 0x33, 0x38, 0x36, 0x38, 0x39, 0x34, 0x32, 0x37, 0x37, 0x34, 0x31, 0x35, 0x35, 0x39, 0x39, 0x31, 0x38, 0x35, 0x4040005a, 0x32, 0x34, 0x35, 0x39, 0x35, 0x33, 0x39, 0x35, 0x39, 0x34, 0x33, 0x31, 0x404005b7, 0x37, 0x40400012, 0x36, 0x38, 0x30, 0x38, 0x34, 0x35, 0x404002e7, 0x37, 0x33, 0x4040081e, 0x39, 0x35, 0x38, 0x34, 0x38, 0x36, 0x35, 0x33, 0x38, 0x404006e8, 0x36, 0x32, 0x404000f2, 0x36, 0x30, 0x39, 0x404004b6, 0x36, 0x30, 0x38, 0x30, 0x35, 0x31, 0x32, 0x34, 0x33, 0x38, 0x38, 0x34, 0x4040013a, 0x4040000b, 0x34, 0x31, 0x33, 0x4040030f, 0x37, 0x36, 0x32, 0x37, 0x38, 0x40400341, 0x37, 0x31, 0x35, 0x4040059b, 0x33, 0x35, 0x39, 0x39, 0x37, 0x37, 0x30, 0x30, 0x31, 0x32, 0x39, 0x40400472, 0x38, 0x39, 0x34, 0x34, 0x31, 0x40400277, 0x36, 0x38, 0x35, 0x35, 0x4040005f, 0x34, 0x30, 0x36, 0x33, 0x404008e6, 0x32, 0x30, 0x37, 0x32, 0x32, 0x40400158, 0x40800203, 0x34, 0x38, 0x31, 0x35, 0x38, 0x40400205, 0x404001fe, 0x4040027a, 0x40400298, 0x33, 0x39, 0x34, 0x35, 0x32, 0x32, 0x36, 0x37, 0x40c00496, 0x38, 0x4040058a, 0x32, 0x31, 0x404002ea, 0x32, 0x40400387, 0x35, 0x34, 0x36, 0x36, 0x36, 0x4040051b, 0x32, 0x33, 0x39, 0x38, 0x36, 0x34, 0x35, 0x36, 0x404004c4, 0x31, 0x36, 0x33, 0x35, 0x40800253, 0x40400811, 0x37, 0x404008ad, 0x39, 0x38, 0x4040045e, 0x39, 0x33, 0x36, 0x33, 0x34, 0x4040075b, 0x37, 0x34, 0x33, 0x32, 0x34, 0x4040047b, 0x31, 0x35, 0x30, 0x37, 0x36, 0x404004bb, 0x37, 0x39, 0x34, 0x35, 0x31, 0x30, 0x39, 0x4040003e, 0x30, 0x39, 0x34, 0x30, 0x404006a6, 0x38, 0x38, 0x37, 0x39, 0x37, 0x31, 0x30, 0x38, 0x39, 0x33, 0x404008f0, 0x36, 0x39, 0x31, 0x33, 0x36, 0x38, 0x36, 0x37, 0x32, 0x4040025b, 0x404001fe, 0x35, 0x4040053f, 0x40400468, 0x40400801, 0x31, 0x37, 0x39, 0x32, 0x38, 0x36, 0x38, 0x404008cc, 0x38, 0x37, 0x34, 0x37, 0x4080079e, 0x38, 0x32, 0x34, 0x4040097a, 0x38, 0x4040025b, 0x37, 0x31, 0x34, 0x39, 0x30, 0x39, 0x36, 0x37, 0x35, 0x39, 0x38, 0x404006ef, 0x33, 0x36, 0x35, 0x40400134, 0x38, 0x31, 0x4040005c, 0x40400745, 0x40400936, 0x36, 0x38, 0x32, 0x39, 0x4040057e, 0x38, 0x37, 0x32, 0x32, 0x36, 0x35, 0x38, 0x38, 0x30, 0x40400611, 0x35, 0x40400249, 0x34, 0x32, 0x37, 0x30, 0x34, 0x37, 0x37, 0x35, 0x35, 0x4040081e, 0x33, 0x37, 0x39, 0x36, 0x34, 0x31, 0x34, 0x35, 0x31, 0x35, 0x32, 0x404005fd, 0x32, 0x33, 0x34, 0x33, 0x36, 0x34, 0x35, 0x34, 0x404005de, 0x34, 0x34, 0x34, 0x37, 0x39, 0x35, 0x4040003c, 0x40400523, 0x408008e6, 0x34, 0x31, 0x4040052a, 0x33, 0x40400304, 0x35, 0x32, 0x33, 0x31, 0x40800841, 0x31, 0x36, 0x36, 0x31, 0x404008b2, 0x35, 0x39, 0x36, 0x39, 0x35, 0x33, 0x36, 0x32, 0x33, 0x31, 0x34, 0x404005ff, 0x32, 0x34, 0x38, 0x34, 0x39, 0x33, 0x37, 0x31, 0x38, 0x37, 0x31, 0x31, 0x30, 0x31, 0x34, 0x35, 0x37, 0x36, 0x35, 0x34, 0x40400761, 0x30, 0x32, 0x37, 0x39, 0x39, 0x33, 0x34, 0x34, 0x30, 0x33, 0x37, 0x34, 0x32, 0x30, 0x30, 0x37, 0x4040093f, 0x37, 0x38, 0x35, 0x33, 0x39, 0x30, 0x36, 0x32, 0x31, 0x39, 0x40800299, 0x40400345, 0x38, 0x34, 0x37, 0x408003d2, 0x38, 0x33, 0x33, 0x32, 0x31, 0x34, 0x34, 0x35, 0x37, 0x31, 0x40400284, 0x40400776, 0x34, 0x33, 0x35, 0x30, 0x40400928, 0x40400468, 0x35, 0x33, 0x31, 0x39, 0x31, 0x30, 0x34, 0x38, 0x34, 0x38, 0x31, 0x30, 0x30, 0x35, 0x33, 0x37, 0x30, 0x36, 0x404008bc, 0x4080059d, 0x40800781, 0x31, 0x40400559, 0x37, 0x4040031b, 0x35, 0x404007ec, 0x4040040c, 0x36, 0x33, 0x408007dc, 0x34, 0x40400971, 0x4080034e, 0x408003f5, 0x38, 0x4080052d, 0x40800887, 0x39, 0x40400187, 0x39, 0x31, 0x404008ce, 0x38, 0x31, 0x34, 0x36, 0x37, 0x35, 0x31, 0x4040062b, 0x31, 0x32, 0x33, 0x39, 0x40c001a9, 0x39, 0x30, 0x37, 0x31, 0x38, 0x36, 0x34, 0x39, 0x34, 0x32, 0x33, 0x31, 0x39, 0x36, 0x31, 0x35, 0x36, 0x404001ec, 0x404006bc, 0x39, 0x35, 0x40400926, 0x40400469, 0x4040011b, 0x36, 0x30, 0x33, 0x38, 0x40400a25, 0x4040016f, 0x40400384, 0x36, 0x32, 0x4040045a, 0x35, 0x4040084c, 0x36, 0x33, 0x38, 0x39, 0x33, 0x37, 0x37, 0x38, 0x37, 0x404008c5, 0x404000f8, 0x39, 0x37, 0x39, 0x32, 0x30, 0x37, 0x37, 0x33, 0x404005d7, 0x32, 0x31, 0x38, 0x32, 0x35, 0x36, 0x404007df, 0x36, 0x36, 0x404006d6, 0x34, 0x32, 0x4080067e, 0x36, 0x404006e6, 0x34, 0x34, 0x40400024, 0x35, 0x34, 0x39, 0x32, 0x30, 0x32, 0x36, 0x30, 0x35, 0x40400ab3, 0x408003e4, 0x32, 0x30, 0x31, 0x34, 0x39, 0x404004d2, 0x38, 0x35, 0x30, 0x37, 0x33, 0x40400599, 0x36, 0x36, 0x36, 0x30, 0x40400194, 0x32, 0x34, 0x33, 0x34, 0x30, 0x40400087, 0x30, 0x4040076b, 0x38, 0x36, 0x33, 0x40400956, 0x404007e4, 0x4040042b, 0x40400174, 0x35, 0x37, 0x39, 0x36, 0x32, 0x36, 0x38, 0x35, 0x36, 0x40400140, 0x35, 0x30, 0x38, 0x40400523, 0x35, 0x38, 0x37, 0x39, 0x36, 0x39, 0x39, 0x40400711, 0x35, 0x37, 0x34, 0x40400a18, 0x38, 0x34, 0x30, 0x404008b3, 0x31, 0x34, 0x35, 0x39, 0x31, 0x4040078c, 0x37, 0x30, 0x40400234, 0x30, 0x31, 0x40400be7, 0x31, 0x32, 0x40400c74, 0x30, 0x404003c3, 0x33, 0x39, 0x40400b2a, 0x40400112, 0x37, 0x31, 0x35, 0x404003b0, 0x34, 0x32, 0x30, 0x40800bf2, 0x39, 0x40400bc2, 0x30, 0x37, 0x40400341, 0x40400795, 0x40400aaf, 0x40400c62, 0x32, 0x31, 0x40400960, 0x32, 0x35, 0x31, 0x4040057b, 0x40400944, 0x39, 0x32, 0x404001b2, 0x38, 0x32, 0x36, 0x40400b66, 0x32, 0x40400278, 0x33, 0x32, 0x31, 0x35, 0x37, 0x39, 0x31, 0x39, 0x38, 0x34, 0x31, 0x34, 0x4080087b, 0x39, 0x31, 0x36, 0x34, 0x408006e8, 0x39, 0x40800b58, 0x404008db, 0x37, 0x32, 0x32, 0x40400321, 0x35, 0x404008a4, 0x40400141, 0x39, 0x31, 0x30, 0x404000bc, 0x40400c5b, 0x35, 0x32, 0x38, 0x30, 0x31, 0x37, 0x40400231, 0x37, 0x31, 0x32, 0x40400914, 0x38, 0x33, 0x32, 0x40400373, 0x31, 0x40400589, 0x30, 0x39, 0x33, 0x35, 0x33, 0x39, 0x36, 0x35, 0x37, 0x4040064b, 0x31, 0x30, 0x38, 0x33, 0x40400069, 0x35, 0x31, 0x4040077a, 0x40400d5a, 0x31, 0x34, 0x34, 0x34, 0x32, 0x31, 0x30, 0x30, 0x40400202, 0x30, 0x33, 0x4040019c, 0x31, 0x31, 0x30, 0x33, 0x40400c81, 0x40400009, 0x40400026, 0x40c00602, 0x35, 0x31, 0x36, 0x404005d9, 0x40800883, 0x4040092a, 0x35, 0x40800c42, 0x38, 0x35, 0x31, 0x37, 0x31, 0x34, 0x33, 0x37, 0x40400605, 0x4040006d, 0x31, 0x35, 0x35, 0x36, 0x35, 0x30, 0x38, 0x38, 0x404003b9, 0x39, 0x38, 0x39, 0x38, 0x35, 0x39, 0x39, 0x38, 0x32, 0x33, 0x38, 0x404001cf, 0x404009ba, 0x33, 0x4040016c, 0x4040043e, 0x404009c3, 0x38, 0x40800e05, 0x33, 0x32, 0x40400107, 0x35, 0x40400305, 0x33, 0x404001ca, 0x39, 0x4040041b, 0x39, 0x38, 0x4040087d, 0x34, 0x40400cb8, 0x37, 0x4040064b, 0x30, 0x37, 0x404000e5, 0x34, 0x38, 0x31, 0x34, 0x31, 0x40400539, 0x38, 0x35, 0x39, 0x34, 0x36, 0x31, 0x40400bc9, 0x38, 0x30},
+ },
+ {
+ input: "testdata/huffman-rand-1k.in",
+ want: "testdata/huffman-rand-1k.%s.expect",
+ wantNoInput: "testdata/huffman-rand-1k.%s.expect-noinput",
+ tokens: []token{0xf8, 0x8b, 0x96, 0x76, 0x48, 0xd, 0x85, 0x94, 0x25, 0x80, 0xaf, 0xc2, 0xfe, 0x8d, 0xe8, 0x20, 0xeb, 0x17, 0x86, 0xc9, 0xb7, 0xc5, 0xde, 0x6, 0xea, 0x7d, 0x18, 0x8b, 0xe7, 0x3e, 0x7, 0xda, 0xdf, 0xff, 0x6c, 0x73, 0xde, 0xcc, 0xe7, 0x6d, 0x8d, 0x4, 0x19, 0x49, 0x7f, 0x47, 0x1f, 0x48, 0x15, 0xb0, 0xe8, 0x9e, 0xf2, 0x31, 0x59, 0xde, 0x34, 0xb4, 0x5b, 0xe5, 0xe0, 0x9, 0x11, 0x30, 0xc2, 0x88, 0x5b, 0x7c, 0x5d, 0x14, 0x13, 0x6f, 0x23, 0xa9, 0xd, 0xbc, 0x2d, 0x23, 0xbe, 0xd9, 0xed, 0x75, 0x4, 0x6c, 0x99, 0xdf, 0xfd, 0x70, 0x66, 0xe6, 0xee, 0xd9, 0xb1, 0x9e, 0x6e, 0x83, 0x59, 0xd5, 0xd4, 0x80, 0x59, 0x98, 0x77, 0x89, 0x43, 0x38, 0xc9, 0xaf, 0x30, 0x32, 0x9a, 0x20, 0x1b, 0x46, 0x3d, 0x67, 0x6e, 0xd7, 0x72, 0x9e, 0x4e, 0x21, 0x4f, 0xc6, 0xe0, 0xd4, 0x7b, 0x4, 0x8d, 0xa5, 0x3, 0xf6, 0x5, 0x9b, 0x6b, 0xdc, 0x2a, 0x93, 0x77, 0x28, 0xfd, 0xb4, 0x62, 0xda, 0x20, 0xe7, 0x1f, 0xab, 0x6b, 0x51, 0x43, 0x39, 0x2f, 0xa0, 0x92, 0x1, 0x6c, 0x75, 0x3e, 0xf4, 0x35, 0xfd, 0x43, 0x2e, 0xf7, 0xa4, 0x75, 0xda, 0xea, 0x9b, 0xa, 0x64, 0xb, 0xe0, 0x23, 0x29, 0xbd, 0xf7, 0xe7, 0x83, 0x3c, 0xfb, 0xdf, 0xb3, 0xae, 0x4f, 0xa4, 0x47, 0x55, 0x99, 0xde, 0x2f, 0x96, 0x6e, 0x1c, 0x43, 0x4c, 0x87, 0xe2, 0x7c, 0xd9, 0x5f, 0x4c, 0x7c, 0xe8, 0x90, 0x3, 0xdb, 0x30, 0x95, 0xd6, 0x22, 0xc, 0x47, 0xb8, 0x4d, 0x6b, 0xbd, 0x24, 0x11, 0xab, 0x2c, 0xd7, 0xbe, 0x6e, 0x7a, 0xd6, 0x8, 0xa3, 0x98, 0xd8, 0xdd, 0x15, 0x6a, 0xfa, 0x93, 0x30, 0x1, 0x25, 0x1d, 0xa2, 0x74, 0x86, 0x4b, 0x6a, 0x95, 0xe8, 0xe1, 0x4e, 0xe, 0x76, 0xb9, 0x49, 0xa9, 0x5f, 0xa0, 0xa6, 0x63, 0x3c, 0x7e, 0x7e, 0x20, 0x13, 0x4f, 0xbb, 0x66, 0x92, 0xb8, 0x2e, 0xa4, 0xfa, 0x48, 0xcb, 0xae, 0xb9, 0x3c, 0xaf, 0xd3, 0x1f, 0xe1, 0xd5, 0x8d, 0x42, 0x6d, 0xf0, 0xfc, 0x8c, 0xc, 0x0, 0xde, 0x40, 0xab, 0x8b, 0x47, 0x97, 0x4e, 0xa8, 0xcf, 0x8e, 0xdb, 0xa6, 0x8b, 0x20, 0x9, 0x84, 0x7a, 0x66, 0xe5, 0x98, 0x29, 0x2, 0x95, 0xe6, 0x38, 0x32, 0x60, 0x3, 0xe3, 0x9a, 0x1e, 0x54, 0xe8, 0x63, 0x80, 0x48, 0x9c, 0xe7, 0x63, 0x33, 0x6e, 0xa0, 0x65, 0x83, 0xfa, 0xc6, 0xba, 0x7a, 0x43, 0x71, 0x5, 0xf5, 0x68, 0x69, 0x85, 0x9c, 0xba, 0x45, 0xcd, 0x6b, 0xb, 0x19, 0xd1, 0xbb, 0x7f, 0x70, 0x85, 0x92, 0xd1, 0xb4, 0x64, 0x82, 0xb1, 0xe4, 0x62, 0xc5, 0x3c, 0x46, 0x1f, 0x92, 0x31, 0x1c, 0x4e, 0x41, 0x77, 0xf7, 0xe7, 0x87, 0xa2, 0xf, 0x6e, 0xe8, 0x92, 0x3, 0x6b, 0xa, 0xe7, 0xa9, 0x3b, 0x11, 0xda, 0x66, 0x8a, 0x29, 0xda, 0x79, 0xe1, 0x64, 0x8d, 0xe3, 0x54, 0xd4, 0xf5, 0xef, 0x64, 0x87, 0x3b, 0xf4, 0xc2, 0xf4, 0x71, 0x13, 0xa9, 0xe9, 0xe0, 0xa2, 0x6, 0x14, 0xab, 0x5d, 0xa7, 0x96, 0x0, 0xd6, 0xc3, 0xcc, 0x57, 0xed, 0x39, 0x6a, 0x25, 0xcd, 0x76, 0xea, 0xba, 0x3a, 0xf2, 0xa1, 0x95, 0x5d, 0xe5, 0x71, 0xcf, 0x9c, 0x62, 0x9e, 0x6a, 0xfa, 0xd5, 0x31, 0xd1, 0xa8, 0x66, 0x30, 0x33, 0xaa, 0x51, 0x17, 0x13, 0x82, 0x99, 0xc8, 0x14, 0x60, 0x9f, 0x4d, 0x32, 0x6d, 0xda, 0x19, 0x26, 0x21, 0xdc, 0x7e, 0x2e, 0x25, 0x67, 0x72, 0xca, 0xf, 0x92, 0xcd, 0xf6, 0xd6, 0xcb, 0x97, 0x8a, 0x33, 0x58, 0x73, 0x70, 0x91, 0x1d, 0xbf, 0x28, 0x23, 0xa3, 0xc, 0xf1, 0x83, 0xc3, 0xc8, 0x56, 0x77, 0x68, 0xe3, 0x82, 0xba, 0xb9, 0x57, 0x56, 0x57, 0x9c, 0xc3, 0xd6, 0x14, 0x5, 0x3c, 0xb1, 0xaf, 0x93, 0xc8, 0x8a, 0x57, 0x7f, 0x53, 0xfa, 0x2f, 0xaa, 0x6e, 0x66, 0x83, 0xfa, 0x33, 0xd1, 0x21, 0xab, 0x1b, 0x71, 0xb4, 0x7c, 0xda, 0xfd, 0xfb, 0x7f, 0x20, 0xab, 0x5e, 0xd5, 0xca, 0xfd, 0xdd, 0xe0, 0xee, 0xda, 0xba, 0xa8, 0x27, 0x99, 0x97, 0x69, 0xc1, 0x3c, 0x82, 0x8c, 0xa, 0x5c, 0x2d, 0x5b, 0x88, 0x3e, 0x34, 0x35, 0x86, 0x37, 0x46, 0x79, 0xe1, 0xaa, 0x19, 0xfb, 0xaa, 0xde, 0x15, 0x9, 0xd, 0x1a, 0x57, 0xff, 0xb5, 0xf, 0xf3, 0x2b, 0x5a, 0x6a, 0x4d, 0x19, 0x77, 0x71, 0x45, 0xdf, 0x4f, 0xb3, 0xec, 0xf1, 0xeb, 0x18, 0x53, 0x3e, 0x3b, 0x47, 0x8, 0x9a, 0x73, 0xa0, 0x5c, 0x8c, 0x5f, 0xeb, 0xf, 0x3a, 0xc2, 0x43, 0x67, 0xb4, 0x66, 0x67, 0x80, 0x58, 0xe, 0xc1, 0xec, 0x40, 0xd4, 0x22, 0x94, 0xca, 0xf9, 0xe8, 0x92, 0xe4, 0x69, 0x38, 0xbe, 0x67, 0x64, 0xca, 0x50, 0xc7, 0x6, 0x67, 0x42, 0x6e, 0xa3, 0xf0, 0xb7, 0x6c, 0xf2, 0xe8, 0x5f, 0xb1, 0xaf, 0xe7, 0xdb, 0xbb, 0x77, 0xb5, 0xf8, 0xcb, 0x8, 0xc4, 0x75, 0x7e, 0xc0, 0xf9, 0x1c, 0x7f, 0x3c, 0x89, 0x2f, 0xd2, 0x58, 0x3a, 0xe2, 0xf8, 0x91, 0xb6, 0x7b, 0x24, 0x27, 0xe9, 0xae, 0x84, 0x8b, 0xde, 0x74, 0xac, 0xfd, 0xd9, 0xb7, 0x69, 0x2a, 0xec, 0x32, 0x6f, 0xf0, 0x92, 0x84, 0xf1, 0x40, 0xc, 0x8a, 0xbc, 0x39, 0x6e, 0x2e, 0x73, 0xd4, 0x6e, 0x8a, 0x74, 0x2a, 0xdc, 0x60, 0x1f, 0xa3, 0x7, 0xde, 0x75, 0x8b, 0x74, 0xc8, 0xfe, 0x63, 0x75, 0xf6, 0x3d, 0x63, 0xac, 0x33, 0x89, 0xc3, 0xf0, 0xf8, 0x2d, 0x6b, 0xb4, 0x9e, 0x74, 0x8b, 0x5c, 0x33, 0xb4, 0xca, 0xa8, 0xe4, 0x99, 0xb6, 0x90, 0xa1, 0xef, 0xf, 0xd3, 0x61, 0xb2, 0xc6, 0x1a, 0x94, 0x7c, 0x44, 0x55, 0xf4, 0x45, 0xff, 0x9e, 0xa5, 0x5a, 0xc6, 0xa0, 0xe8, 0x2a, 0xc1, 0x8d, 0x6f, 0x34, 0x11, 0xb9, 0xbe, 0x4e, 0xd9, 0x87, 0x97, 0x73, 0xcf, 0x3d, 0x23, 0xae, 0xd5, 0x1a, 0x5e, 0xae, 0x5d, 0x6a, 0x3, 0xf9, 0x22, 0xd, 0x10, 0xd9, 0x47, 0x69, 0x15, 0x3f, 0xee, 0x52, 0xa3, 0x8, 0xd2, 0x3c, 0x51, 0xf4, 0xf8, 0x9d, 0xe4, 0x98, 0x89, 0xc8, 0x67, 0x39, 0xd5, 0x5e, 0x35, 0x78, 0x27, 0xe8, 0x3c, 0x80, 0xae, 0x79, 0x71, 0xd2, 0x93, 0xf4, 0xaa, 0x51, 0x12, 0x1c, 0x4b, 0x1b, 0xe5, 0x6e, 0x15, 0x6f, 0xe4, 0xbb, 0x51, 0x9b, 0x45, 0x9f, 0xf9, 0xc4, 0x8c, 0x2a, 0xfb, 0x1a, 0xdf, 0x55, 0xd3, 0x48, 0x93, 0x27, 0x1, 0x26, 0xc2, 0x6b, 0x55, 0x6d, 0xa2, 0xfb, 0x84, 0x8b, 0xc9, 0x9e, 0x28, 0xc2, 0xef, 0x1a, 0x24, 0xec, 0x9b, 0xae, 0xbd, 0x60, 0xe9, 0x15, 0x35, 0xee, 0x42, 0xa4, 0x33, 0x5b, 0xfa, 0xf, 0xb6, 0xf7, 0x1, 0xa6, 0x2, 0x4c, 0xca, 0x90, 0x58, 0x3a, 0x96, 0x41, 0xe7, 0xcb, 0x9, 0x8c, 0xdb, 0x85, 0x4d, 0xa8, 0x89, 0xf3, 0xb5, 0x8e, 0xfd, 0x75, 0x5b, 0x4f, 0xed, 0xde, 0x3f, 0xeb, 0x38, 0xa3, 0xbe, 0xb0, 0x73, 0xfc, 0xb8, 0x54, 0xf7, 0x4c, 0x30, 0x67, 0x2e, 0x38, 0xa2, 0x54, 0x18, 0xba, 0x8, 0xbf, 0xf2, 0x39, 0xd5, 0xfe, 0xa5, 0x41, 0xc6, 0x66, 0x66, 0xba, 0x81, 0xef, 0x67, 0xe4, 0xe6, 0x3c, 0xc, 0xca, 0xa4, 0xa, 0x79, 0xb3, 0x57, 0x8b, 0x8a, 0x75, 0x98, 0x18, 0x42, 0x2f, 0x29, 0xa3, 0x82, 0xef, 0x9f, 0x86, 0x6, 0x23, 0xe1, 0x75, 0xfa, 0x8, 0xb1, 0xde, 0x17, 0x4a},
+ },
+ {
+ input: "testdata/huffman-rand-limit.in",
+ want: "testdata/huffman-rand-limit.%s.expect",
+ wantNoInput: "testdata/huffman-rand-limit.%s.expect-noinput",
+ tokens: []token{0x61, 0x51c00000, 0xa, 0xf8, 0x8b, 0x96, 0x76, 0x48, 0xa, 0x85, 0x94, 0x25, 0x80, 0xaf, 0xc2, 0xfe, 0x8d, 0xe8, 0x20, 0xeb, 0x17, 0x86, 0xc9, 0xb7, 0xc5, 0xde, 0x6, 0xea, 0x7d, 0x18, 0x8b, 0xe7, 0x3e, 0x7, 0xda, 0xdf, 0xff, 0x6c, 0x73, 0xde, 0xcc, 0xe7, 0x6d, 0x8d, 0x4, 0x19, 0x49, 0x7f, 0x47, 0x1f, 0x48, 0x15, 0xb0, 0xe8, 0x9e, 0xf2, 0x31, 0x59, 0xde, 0x34, 0xb4, 0x5b, 0xe5, 0xe0, 0x9, 0x11, 0x30, 0xc2, 0x88, 0x5b, 0x7c, 0x5d, 0x14, 0x13, 0x6f, 0x23, 0xa9, 0xa, 0xbc, 0x2d, 0x23, 0xbe, 0xd9, 0xed, 0x75, 0x4, 0x6c, 0x99, 0xdf, 0xfd, 0x70, 0x66, 0xe6, 0xee, 0xd9, 0xb1, 0x9e, 0x6e, 0x83, 0x59, 0xd5, 0xd4, 0x80, 0x59, 0x98, 0x77, 0x89, 0x43, 0x38, 0xc9, 0xaf, 0x30, 0x32, 0x9a, 0x20, 0x1b, 0x46, 0x3d, 0x67, 0x6e, 0xd7, 0x72, 0x9e, 0x4e, 0x21, 0x4f, 0xc6, 0xe0, 0xd4, 0x7b, 0x4, 0x8d, 0xa5, 0x3, 0xf6, 0x5, 0x9b, 0x6b, 0xdc, 0x2a, 0x93, 0x77, 0x28, 0xfd, 0xb4, 0x62, 0xda, 0x20, 0xe7, 0x1f, 0xab, 0x6b, 0x51, 0x43, 0x39, 0x2f, 0xa0, 0x92, 0x1, 0x6c, 0x75, 0x3e, 0xf4, 0x35, 0xfd, 0x43, 0x2e, 0xf7, 0xa4, 0x75, 0xda, 0xea, 0x9b, 0xa},
+ },
+ {
+ input: "testdata/huffman-shifts.in",
+ want: "testdata/huffman-shifts.%s.expect",
+ wantNoInput: "testdata/huffman-shifts.%s.expect-noinput",
+ tokens: []token{0x31, 0x30, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x52400001, 0xd, 0xa, 0x32, 0x33, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7fc00001, 0x7f400001},
+ },
+ {
+ input: "testdata/huffman-text-shift.in",
+ want: "testdata/huffman-text-shift.%s.expect",
+ wantNoInput: "testdata/huffman-text-shift.%s.expect-noinput",
+ tokens: []token{0x2f, 0x2f, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x32, 0x30, 0x30, 0x39, 0x54, 0x68, 0x47, 0x6f, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x2e, 0x41, 0x6c, 0x6c, 0x40800016, 0x72, 0x72, 0x76, 0x64, 0x2e, 0xd, 0xa, 0x2f, 0x2f, 0x55, 0x6f, 0x66, 0x74, 0x68, 0x69, 0x6f, 0x75, 0x72, 0x63, 0x63, 0x6f, 0x64, 0x69, 0x67, 0x6f, 0x76, 0x72, 0x6e, 0x64, 0x62, 0x79, 0x42, 0x53, 0x44, 0x2d, 0x74, 0x79, 0x6c, 0x40400020, 0x6c, 0x69, 0x63, 0x6e, 0x74, 0x68, 0x74, 0x63, 0x6e, 0x62, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x74, 0x68, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x66, 0x69, 0x6c, 0x2e, 0xd, 0xa, 0xd, 0xa, 0x70, 0x63, 0x6b, 0x67, 0x6d, 0x69, 0x6e, 0x4040000a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x6f, 0x22, 0x4040000c, 0x66, 0x75, 0x6e, 0x63, 0x6d, 0x69, 0x6e, 0x28, 0x29, 0x7b, 0xd, 0xa, 0x9, 0x76, 0x72, 0x62, 0x3d, 0x6d, 0x6b, 0x28, 0x5b, 0x5d, 0x62, 0x79, 0x74, 0x2c, 0x36, 0x35, 0x35, 0x33, 0x35, 0x29, 0xd, 0xa, 0x9, 0x66, 0x2c, 0x5f, 0x3a, 0x3d, 0x6f, 0x2e, 0x43, 0x72, 0x74, 0x28, 0x22, 0x68, 0x75, 0x66, 0x66, 0x6d, 0x6e, 0x2d, 0x6e, 0x75, 0x6c, 0x6c, 0x2d, 0x6d, 0x78, 0x2e, 0x69, 0x6e, 0x22, 0x40800021, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x28, 0x62, 0x29, 0xd, 0xa, 0x7d, 0xd, 0xa, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x58, 0x78, 0x79, 0x7a, 0x21, 0x22, 0x23, 0xc2, 0xa4, 0x25, 0x26, 0x2f, 0x3f, 0x22},
+ },
+ {
+ input: "testdata/huffman-text.in",
+ want: "testdata/huffman-text.%s.expect",
+ wantNoInput: "testdata/huffman-text.%s.expect-noinput",
+ tokens: []token{0x2f, 0x2f, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x54, 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x73, 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x4080001e, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0xd, 0xa, 0x2f, 0x2f, 0x20, 0x55, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x42, 0x53, 0x44, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x40800036, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0xd, 0xa, 0xd, 0xa, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x4040000f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x22, 0x6f, 0x73, 0x22, 0x4040000e, 0x66, 0x75, 0x6e, 0x63, 0x4080001b, 0x28, 0x29, 0x20, 0x7b, 0xd, 0xa, 0x9, 0x76, 0x61, 0x72, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x28, 0x5b, 0x5d, 0x62, 0x79, 0x74, 0x65, 0x2c, 0x20, 0x36, 0x35, 0x35, 0x33, 0x35, 0x29, 0xd, 0xa, 0x9, 0x66, 0x2c, 0x20, 0x5f, 0x20, 0x3a, 0x3d, 0x20, 0x6f, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x28, 0x22, 0x68, 0x75, 0x66, 0x66, 0x6d, 0x61, 0x6e, 0x2d, 0x6e, 0x75, 0x6c, 0x6c, 0x2d, 0x6d, 0x61, 0x78, 0x2e, 0x69, 0x6e, 0x22, 0x4080002a, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x28, 0x62, 0x29, 0xd, 0xa, 0x7d, 0xd, 0xa},
+ },
+ {
+ input: "testdata/huffman-zero.in",
+ want: "testdata/huffman-zero.%s.expect",
+ wantNoInput: "testdata/huffman-zero.%s.expect-noinput",
+ tokens: []token{0x30, ml, 0x4b800000},
+ },
+ {
+ input: "",
+ want: "",
+ wantNoInput: "testdata/null-long-match.%s.expect-noinput",
+ tokens: []token{0x0, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, ml, 0x41400000},
+ },
+}
+
+// TestWriteBlock tests if the writeBlock encoding has changed.
+// To update the reference files use the "-update" flag on the test.
+func TestWriteBlock(t *testing.T) {
+ for _, test := range writeBlockTests {
+ testBlock(t, test, "wb")
+ }
+}
+
+// TestWriteBlockDynamic tests if the writeBlockDynamic encoding has changed.
+// To update the reference files use the "-update" flag on the test.
+func TestWriteBlockDynamic(t *testing.T) {
+ for _, test := range writeBlockTests {
+ testBlock(t, test, "dyn")
+ }
+}
+
+// testBlock tests a block against its references,
+// or regenerate the references, if "-update" flag is set.
+func testBlock(t *testing.T, test huffTest, ttype string) {
+ if test.want != "" {
+ test.want = fmt.Sprintf(test.want, ttype)
+ }
+ test.wantNoInput = fmt.Sprintf(test.wantNoInput, ttype)
+ if *update {
+ if test.input != "" {
+ t.Logf("Updating %q", test.want)
+ input, err := os.ReadFile(test.input)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ f, err := os.Create(test.want)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer f.Close()
+ bw := newHuffmanBitWriter(f)
+ writeToType(t, ttype, bw, test.tokens, input)
+ }
+
+ t.Logf("Updating %q", test.wantNoInput)
+ f, err := os.Create(test.wantNoInput)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer f.Close()
+ bw := newHuffmanBitWriter(f)
+ writeToType(t, ttype, bw, test.tokens, nil)
+ return
+ }
+
+ if test.input != "" {
+ t.Logf("Testing %q", test.want)
+ input, err := os.ReadFile(test.input)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ want, err := os.ReadFile(test.want)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ var buf bytes.Buffer
+ bw := newHuffmanBitWriter(&buf)
+ writeToType(t, ttype, bw, test.tokens, input)
+
+ got := buf.Bytes()
+ if !bytes.Equal(got, want) {
+ t.Errorf("writeBlock did not yield expected result for file %q with input. See %q", test.want, test.want+".got")
+ if err := os.WriteFile(test.want+".got", got, 0666); err != nil {
+ t.Error(err)
+ }
+ }
+ t.Log("Output ok")
+
+ // Test if the writer produces the same output after reset.
+ buf.Reset()
+ bw.reset(&buf)
+ writeToType(t, ttype, bw, test.tokens, input)
+ bw.flush()
+ got = buf.Bytes()
+ if !bytes.Equal(got, want) {
+ t.Errorf("reset: writeBlock did not yield expected result for file %q with input. See %q", test.want, test.want+".reset.got")
+ if err := os.WriteFile(test.want+".reset.got", got, 0666); err != nil {
+ t.Error(err)
+ }
+ return
+ }
+ t.Log("Reset ok")
+ testWriterEOF(t, "wb", test, true)
+ }
+ t.Logf("Testing %q", test.wantNoInput)
+ wantNI, err := os.ReadFile(test.wantNoInput)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ var buf bytes.Buffer
+ bw := newHuffmanBitWriter(&buf)
+ writeToType(t, ttype, bw, test.tokens, nil)
+
+ got := buf.Bytes()
+ if !bytes.Equal(got, wantNI) {
+ t.Errorf("writeBlock did not yield expected result for file %q with input. See %q", test.wantNoInput, test.wantNoInput+".got")
+ if err := os.WriteFile(test.want+".got", got, 0666); err != nil {
+ t.Error(err)
+ }
+ } else if got[0]&1 == 1 {
+ t.Error("got unexpected EOF")
+ return
+ }
+
+ t.Log("Output ok")
+
+ // Test if the writer produces the same output after reset.
+ buf.Reset()
+ bw.reset(&buf)
+ writeToType(t, ttype, bw, test.tokens, nil)
+ bw.flush()
+ got = buf.Bytes()
+ if !bytes.Equal(got, wantNI) {
+ t.Errorf("reset: writeBlock did not yield expected result for file %q without input. See %q", test.want, test.want+".reset.got")
+ if err := os.WriteFile(test.want+".reset.got", got, 0666); err != nil {
+ t.Error(err)
+ }
+ return
+ }
+ t.Log("Reset ok")
+ testWriterEOF(t, "wb", test, false)
+}
+
+func writeToType(t *testing.T, ttype string, bw *huffmanBitWriter, tok []token, input []byte) {
+ switch ttype {
+ case "wb":
+ bw.writeBlock(tok, false, input)
+ case "dyn":
+ bw.writeBlockDynamic(tok, false, input)
+ default:
+ panic("unknown test type")
+ }
+
+ if bw.err != nil {
+ t.Error(bw.err)
+ return
+ }
+
+ bw.flush()
+ if bw.err != nil {
+ t.Error(bw.err)
+ return
+ }
+}
+
+// testWriterEOF tests if the written block contains an EOF marker.
+func testWriterEOF(t *testing.T, ttype string, test huffTest, useInput bool) {
+ if useInput && test.input == "" {
+ return
+ }
+ var input []byte
+ if useInput {
+ var err error
+ input, err = os.ReadFile(test.input)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ }
+ var buf bytes.Buffer
+ bw := newHuffmanBitWriter(&buf)
+ switch ttype {
+ case "wb":
+ bw.writeBlock(test.tokens, true, input)
+ case "dyn":
+ bw.writeBlockDynamic(test.tokens, true, input)
+ case "huff":
+ bw.writeBlockHuff(true, input)
+ default:
+ panic("unknown test type")
+ }
+ if bw.err != nil {
+ t.Error(bw.err)
+ return
+ }
+
+ bw.flush()
+ if bw.err != nil {
+ t.Error(bw.err)
+ return
+ }
+ b := buf.Bytes()
+ if len(b) == 0 {
+ t.Error("no output received")
+ return
+ }
+ if b[0]&1 != 1 {
+ t.Errorf("block not marked with EOF for input %q", test.input)
+ return
+ }
+ t.Log("EOF ok")
+}
diff --git a/src/compress/flate/huffman_code.go b/src/compress/flate/huffman_code.go
new file mode 100644
index 0000000..ade4c8f
--- /dev/null
+++ b/src/compress/flate/huffman_code.go
@@ -0,0 +1,345 @@
+// Copyright 2009 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 flate
+
+import (
+ "math"
+ "math/bits"
+ "sort"
+)
+
+// hcode is a huffman code with a bit code and bit length.
+type hcode struct {
+ code, len uint16
+}
+
+type huffmanEncoder struct {
+ codes []hcode
+ freqcache []literalNode
+ bitCount [17]int32
+ lns byLiteral // stored to avoid repeated allocation in generate
+ lfs byFreq // stored to avoid repeated allocation in generate
+}
+
+type literalNode struct {
+ literal uint16
+ freq int32
+}
+
+// A levelInfo describes the state of the constructed tree for a given depth.
+type levelInfo struct {
+ // Our level. for better printing
+ level int32
+
+ // The frequency of the last node at this level
+ lastFreq int32
+
+ // The frequency of the next character to add to this level
+ nextCharFreq int32
+
+ // The frequency of the next pair (from level below) to add to this level.
+ // Only valid if the "needed" value of the next lower level is 0.
+ nextPairFreq int32
+
+ // The number of chains remaining to generate for this level before moving
+ // up to the next level
+ needed int32
+}
+
+// set sets the code and length of an hcode.
+func (h *hcode) set(code uint16, length uint16) {
+ h.len = length
+ h.code = code
+}
+
+func maxNode() literalNode { return literalNode{math.MaxUint16, math.MaxInt32} }
+
+func newHuffmanEncoder(size int) *huffmanEncoder {
+ return &huffmanEncoder{codes: make([]hcode, size)}
+}
+
+// Generates a HuffmanCode corresponding to the fixed literal table.
+func generateFixedLiteralEncoding() *huffmanEncoder {
+ h := newHuffmanEncoder(maxNumLit)
+ codes := h.codes
+ var ch uint16
+ for ch = 0; ch < maxNumLit; ch++ {
+ var bits uint16
+ var size uint16
+ switch {
+ case ch < 144:
+ // size 8, 000110000 .. 10111111
+ bits = ch + 48
+ size = 8
+ case ch < 256:
+ // size 9, 110010000 .. 111111111
+ bits = ch + 400 - 144
+ size = 9
+ case ch < 280:
+ // size 7, 0000000 .. 0010111
+ bits = ch - 256
+ size = 7
+ default:
+ // size 8, 11000000 .. 11000111
+ bits = ch + 192 - 280
+ size = 8
+ }
+ codes[ch] = hcode{code: reverseBits(bits, byte(size)), len: size}
+ }
+ return h
+}
+
+func generateFixedOffsetEncoding() *huffmanEncoder {
+ h := newHuffmanEncoder(30)
+ codes := h.codes
+ for ch := range codes {
+ codes[ch] = hcode{code: reverseBits(uint16(ch), 5), len: 5}
+ }
+ return h
+}
+
+var fixedLiteralEncoding *huffmanEncoder = generateFixedLiteralEncoding()
+var fixedOffsetEncoding *huffmanEncoder = generateFixedOffsetEncoding()
+
+func (h *huffmanEncoder) bitLength(freq []int32) int {
+ var total int
+ for i, f := range freq {
+ if f != 0 {
+ total += int(f) * int(h.codes[i].len)
+ }
+ }
+ return total
+}
+
+const maxBitsLimit = 16
+
+// bitCounts computes the number of literals assigned to each bit size in the Huffman encoding.
+// It is only called when list.length >= 3.
+// The cases of 0, 1, and 2 literals are handled by special case code.
+//
+// list is an array of the literals with non-zero frequencies
+// and their associated frequencies. The array is in order of increasing
+// frequency and has as its last element a special element with frequency
+// MaxInt32.
+//
+// maxBits is the maximum number of bits that should be used to encode any literal.
+// It must be less than 16.
+//
+// bitCounts returns an integer slice in which slice[i] indicates the number of literals
+// that should be encoded in i bits.
+func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 {
+ if maxBits >= maxBitsLimit {
+ panic("flate: maxBits too large")
+ }
+ n := int32(len(list))
+ list = list[0 : n+1]
+ list[n] = maxNode()
+
+ // The tree can't have greater depth than n - 1, no matter what. This
+ // saves a little bit of work in some small cases
+ if maxBits > n-1 {
+ maxBits = n - 1
+ }
+
+ // Create information about each of the levels.
+ // A bogus "Level 0" whose sole purpose is so that
+ // level1.prev.needed==0. This makes level1.nextPairFreq
+ // be a legitimate value that never gets chosen.
+ var levels [maxBitsLimit]levelInfo
+ // leafCounts[i] counts the number of literals at the left
+ // of ancestors of the rightmost node at level i.
+ // leafCounts[i][j] is the number of literals at the left
+ // of the level j ancestor.
+ var leafCounts [maxBitsLimit][maxBitsLimit]int32
+
+ for level := int32(1); level <= maxBits; level++ {
+ // For every level, the first two items are the first two characters.
+ // We initialize the levels as if we had already figured this out.
+ levels[level] = levelInfo{
+ level: level,
+ lastFreq: list[1].freq,
+ nextCharFreq: list[2].freq,
+ nextPairFreq: list[0].freq + list[1].freq,
+ }
+ leafCounts[level][level] = 2
+ if level == 1 {
+ levels[level].nextPairFreq = math.MaxInt32
+ }
+ }
+
+ // We need a total of 2*n - 2 items at top level and have already generated 2.
+ levels[maxBits].needed = 2*n - 4
+
+ level := maxBits
+ for {
+ l := &levels[level]
+ if l.nextPairFreq == math.MaxInt32 && l.nextCharFreq == math.MaxInt32 {
+ // We've run out of both leafs and pairs.
+ // End all calculations for this level.
+ // To make sure we never come back to this level or any lower level,
+ // set nextPairFreq impossibly large.
+ l.needed = 0
+ levels[level+1].nextPairFreq = math.MaxInt32
+ level++
+ continue
+ }
+
+ prevFreq := l.lastFreq
+ if l.nextCharFreq < l.nextPairFreq {
+ // The next item on this row is a leaf node.
+ n := leafCounts[level][level] + 1
+ l.lastFreq = l.nextCharFreq
+ // Lower leafCounts are the same of the previous node.
+ leafCounts[level][level] = n
+ l.nextCharFreq = list[n].freq
+ } else {
+ // The next item on this row is a pair from the previous row.
+ // nextPairFreq isn't valid until we generate two
+ // more values in the level below
+ l.lastFreq = l.nextPairFreq
+ // Take leaf counts from the lower level, except counts[level] remains the same.
+ copy(leafCounts[level][:level], leafCounts[level-1][:level])
+ levels[l.level-1].needed = 2
+ }
+
+ if l.needed--; l.needed == 0 {
+ // We've done everything we need to do for this level.
+ // Continue calculating one level up. Fill in nextPairFreq
+ // of that level with the sum of the two nodes we've just calculated on
+ // this level.
+ if l.level == maxBits {
+ // All done!
+ break
+ }
+ levels[l.level+1].nextPairFreq = prevFreq + l.lastFreq
+ level++
+ } else {
+ // If we stole from below, move down temporarily to replenish it.
+ for levels[level-1].needed > 0 {
+ level--
+ }
+ }
+ }
+
+ // Somethings is wrong if at the end, the top level is null or hasn't used
+ // all of the leaves.
+ if leafCounts[maxBits][maxBits] != n {
+ panic("leafCounts[maxBits][maxBits] != n")
+ }
+
+ bitCount := h.bitCount[:maxBits+1]
+ bits := 1
+ counts := &leafCounts[maxBits]
+ for level := maxBits; level > 0; level-- {
+ // chain.leafCount gives the number of literals requiring at least "bits"
+ // bits to encode.
+ bitCount[bits] = counts[level] - counts[level-1]
+ bits++
+ }
+ return bitCount
+}
+
+// Look at the leaves and assign them a bit count and an encoding as specified
+// in RFC 1951 3.2.2
+func (h *huffmanEncoder) assignEncodingAndSize(bitCount []int32, list []literalNode) {
+ code := uint16(0)
+ for n, bits := range bitCount {
+ code <<= 1
+ if n == 0 || bits == 0 {
+ continue
+ }
+ // The literals list[len(list)-bits] .. list[len(list)-bits]
+ // are encoded using "bits" bits, and get the values
+ // code, code + 1, .... The code values are
+ // assigned in literal order (not frequency order).
+ chunk := list[len(list)-int(bits):]
+
+ h.lns.sort(chunk)
+ for _, node := range chunk {
+ h.codes[node.literal] = hcode{code: reverseBits(code, uint8(n)), len: uint16(n)}
+ code++
+ }
+ list = list[0 : len(list)-int(bits)]
+ }
+}
+
+// Update this Huffman Code object to be the minimum code for the specified frequency count.
+//
+// freq is an array of frequencies, in which freq[i] gives the frequency of literal i.
+// maxBits The maximum number of bits to use for any literal.
+func (h *huffmanEncoder) generate(freq []int32, maxBits int32) {
+ if h.freqcache == nil {
+ // Allocate a reusable buffer with the longest possible frequency table.
+ // Possible lengths are codegenCodeCount, offsetCodeCount and maxNumLit.
+ // The largest of these is maxNumLit, so we allocate for that case.
+ h.freqcache = make([]literalNode, maxNumLit+1)
+ }
+ list := h.freqcache[:len(freq)+1]
+ // Number of non-zero literals
+ count := 0
+ // Set list to be the set of all non-zero literals and their frequencies
+ for i, f := range freq {
+ if f != 0 {
+ list[count] = literalNode{uint16(i), f}
+ count++
+ } else {
+ h.codes[i].len = 0
+ }
+ }
+
+ list = list[:count]
+ if count <= 2 {
+ // Handle the small cases here, because they are awkward for the general case code. With
+ // two or fewer literals, everything has bit length 1.
+ for i, node := range list {
+ // "list" is in order of increasing literal value.
+ h.codes[node.literal].set(uint16(i), 1)
+ }
+ return
+ }
+ h.lfs.sort(list)
+
+ // Get the number of literals for each bit count
+ bitCount := h.bitCounts(list, maxBits)
+ // And do the assignment
+ h.assignEncodingAndSize(bitCount, list)
+}
+
+type byLiteral []literalNode
+
+func (s *byLiteral) sort(a []literalNode) {
+ *s = byLiteral(a)
+ sort.Sort(s)
+}
+
+func (s byLiteral) Len() int { return len(s) }
+
+func (s byLiteral) Less(i, j int) bool {
+ return s[i].literal < s[j].literal
+}
+
+func (s byLiteral) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+type byFreq []literalNode
+
+func (s *byFreq) sort(a []literalNode) {
+ *s = byFreq(a)
+ sort.Sort(s)
+}
+
+func (s byFreq) Len() int { return len(s) }
+
+func (s byFreq) Less(i, j int) bool {
+ if s[i].freq == s[j].freq {
+ return s[i].literal < s[j].literal
+ }
+ return s[i].freq < s[j].freq
+}
+
+func (s byFreq) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+func reverseBits(number uint16, bitLength byte) uint16 {
+ return bits.Reverse16(number << (16 - bitLength))
+}
diff --git a/src/compress/flate/inflate.go b/src/compress/flate/inflate.go
new file mode 100644
index 0000000..d7375f2
--- /dev/null
+++ b/src/compress/flate/inflate.go
@@ -0,0 +1,836 @@
+// Copyright 2009 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 flate implements the DEFLATE compressed data format, described in
+// RFC 1951. The gzip and zlib packages implement access to DEFLATE-based file
+// formats.
+package flate
+
+import (
+ "bufio"
+ "io"
+ "math/bits"
+ "strconv"
+ "sync"
+)
+
+const (
+ maxCodeLen = 16 // max length of Huffman code
+ // The next three numbers come from the RFC section 3.2.7, with the
+ // additional proviso in section 3.2.5 which implies that distance codes
+ // 30 and 31 should never occur in compressed data.
+ maxNumLit = 286
+ maxNumDist = 30
+ numCodes = 19 // number of codes in Huffman meta-code
+)
+
+// Initialize the fixedHuffmanDecoder only once upon first use.
+var fixedOnce sync.Once
+var fixedHuffmanDecoder huffmanDecoder
+
+// A CorruptInputError reports the presence of corrupt input at a given offset.
+type CorruptInputError int64
+
+func (e CorruptInputError) Error() string {
+ return "flate: corrupt input before offset " + strconv.FormatInt(int64(e), 10)
+}
+
+// An InternalError reports an error in the flate code itself.
+type InternalError string
+
+func (e InternalError) Error() string { return "flate: internal error: " + string(e) }
+
+// A ReadError reports an error encountered while reading input.
+//
+// Deprecated: No longer returned.
+type ReadError struct {
+ Offset int64 // byte offset where error occurred
+ Err error // error returned by underlying Read
+}
+
+func (e *ReadError) Error() string {
+ return "flate: read error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
+}
+
+// A WriteError reports an error encountered while writing output.
+//
+// Deprecated: No longer returned.
+type WriteError struct {
+ Offset int64 // byte offset where error occurred
+ Err error // error returned by underlying Write
+}
+
+func (e *WriteError) Error() string {
+ return "flate: write error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
+}
+
+// Resetter resets a ReadCloser returned by NewReader or NewReaderDict
+// to switch to a new underlying Reader. This permits reusing a ReadCloser
+// instead of allocating a new one.
+type Resetter interface {
+ // Reset discards any buffered data and resets the Resetter as if it was
+ // newly initialized with the given reader.
+ Reset(r io.Reader, dict []byte) error
+}
+
+// The data structure for decoding Huffman tables is based on that of
+// zlib. There is a lookup table of a fixed bit width (huffmanChunkBits),
+// For codes smaller than the table width, there are multiple entries
+// (each combination of trailing bits has the same value). For codes
+// larger than the table width, the table contains a link to an overflow
+// table. The width of each entry in the link table is the maximum code
+// size minus the chunk width.
+//
+// Note that you can do a lookup in the table even without all bits
+// filled. Since the extra bits are zero, and the DEFLATE Huffman codes
+// have the property that shorter codes come before longer ones, the
+// bit length estimate in the result is a lower bound on the actual
+// number of bits.
+//
+// See the following:
+// https://github.com/madler/zlib/raw/master/doc/algorithm.txt
+
+// chunk & 15 is number of bits
+// chunk >> 4 is value, including table link
+
+const (
+ huffmanChunkBits = 9
+ huffmanNumChunks = 1 << huffmanChunkBits
+ huffmanCountMask = 15
+ huffmanValueShift = 4
+)
+
+type huffmanDecoder struct {
+ min int // the minimum code length
+ chunks [huffmanNumChunks]uint32 // chunks as described above
+ links [][]uint32 // overflow links
+ linkMask uint32 // mask the width of the link table
+}
+
+// Initialize Huffman decoding tables from array of code lengths.
+// Following this function, h is guaranteed to be initialized into a complete
+// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a
+// degenerate case where the tree has only a single symbol with length 1. Empty
+// trees are permitted.
+func (h *huffmanDecoder) init(lengths []int) bool {
+ // Sanity enables additional runtime tests during Huffman
+ // table construction. It's intended to be used during
+ // development to supplement the currently ad-hoc unit tests.
+ const sanity = false
+
+ if h.min != 0 {
+ *h = huffmanDecoder{}
+ }
+
+ // Count number of codes of each length,
+ // compute min and max length.
+ var count [maxCodeLen]int
+ var min, max int
+ for _, n := range lengths {
+ if n == 0 {
+ continue
+ }
+ if min == 0 || n < min {
+ min = n
+ }
+ if n > max {
+ max = n
+ }
+ count[n]++
+ }
+
+ // Empty tree. The decompressor.huffSym function will fail later if the tree
+ // is used. Technically, an empty tree is only valid for the HDIST tree and
+ // not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree
+ // is guaranteed to fail since it will attempt to use the tree to decode the
+ // codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is
+ // guaranteed to fail later since the compressed data section must be
+ // composed of at least one symbol (the end-of-block marker).
+ if max == 0 {
+ return true
+ }
+
+ code := 0
+ var nextcode [maxCodeLen]int
+ for i := min; i <= max; i++ {
+ code <<= 1
+ nextcode[i] = code
+ code += count[i]
+ }
+
+ // Check that the coding is complete (i.e., that we've
+ // assigned all 2-to-the-max possible bit sequences).
+ // Exception: To be compatible with zlib, we also need to
+ // accept degenerate single-code codings. See also
+ // TestDegenerateHuffmanCoding.
+ if code != 1<<uint(max) && !(code == 1 && max == 1) {
+ return false
+ }
+
+ h.min = min
+ if max > huffmanChunkBits {
+ numLinks := 1 << (uint(max) - huffmanChunkBits)
+ h.linkMask = uint32(numLinks - 1)
+
+ // create link tables
+ link := nextcode[huffmanChunkBits+1] >> 1
+ h.links = make([][]uint32, huffmanNumChunks-link)
+ for j := uint(link); j < huffmanNumChunks; j++ {
+ reverse := int(bits.Reverse16(uint16(j)))
+ reverse >>= uint(16 - huffmanChunkBits)
+ off := j - uint(link)
+ if sanity && h.chunks[reverse] != 0 {
+ panic("impossible: overwriting existing chunk")
+ }
+ h.chunks[reverse] = uint32(off<<huffmanValueShift | (huffmanChunkBits + 1))
+ h.links[off] = make([]uint32, numLinks)
+ }
+ }
+
+ for i, n := range lengths {
+ if n == 0 {
+ continue
+ }
+ code := nextcode[n]
+ nextcode[n]++
+ chunk := uint32(i<<huffmanValueShift | n)
+ reverse := int(bits.Reverse16(uint16(code)))
+ reverse >>= uint(16 - n)
+ if n <= huffmanChunkBits {
+ for off := reverse; off < len(h.chunks); off += 1 << uint(n) {
+ // We should never need to overwrite
+ // an existing chunk. Also, 0 is
+ // never a valid chunk, because the
+ // lower 4 "count" bits should be
+ // between 1 and 15.
+ if sanity && h.chunks[off] != 0 {
+ panic("impossible: overwriting existing chunk")
+ }
+ h.chunks[off] = chunk
+ }
+ } else {
+ j := reverse & (huffmanNumChunks - 1)
+ if sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 {
+ // Longer codes should have been
+ // associated with a link table above.
+ panic("impossible: not an indirect chunk")
+ }
+ value := h.chunks[j] >> huffmanValueShift
+ linktab := h.links[value]
+ reverse >>= huffmanChunkBits
+ for off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) {
+ if sanity && linktab[off] != 0 {
+ panic("impossible: overwriting existing chunk")
+ }
+ linktab[off] = chunk
+ }
+ }
+ }
+
+ if sanity {
+ // Above we've sanity checked that we never overwrote
+ // an existing entry. Here we additionally check that
+ // we filled the tables completely.
+ for i, chunk := range h.chunks {
+ if chunk == 0 {
+ // As an exception, in the degenerate
+ // single-code case, we allow odd
+ // chunks to be missing.
+ if code == 1 && i%2 == 1 {
+ continue
+ }
+ panic("impossible: missing chunk")
+ }
+ }
+ for _, linktab := range h.links {
+ for _, chunk := range linktab {
+ if chunk == 0 {
+ panic("impossible: missing chunk")
+ }
+ }
+ }
+ }
+
+ return true
+}
+
+// The actual read interface needed by NewReader.
+// If the passed in io.Reader does not also have ReadByte,
+// the NewReader will introduce its own buffering.
+type Reader interface {
+ io.Reader
+ io.ByteReader
+}
+
+// Decompress state.
+type decompressor struct {
+ // Input source.
+ r Reader
+ rBuf *bufio.Reader // created if provided io.Reader does not implement io.ByteReader
+ roffset int64
+
+ // Input bits, in top of b.
+ b uint32
+ nb uint
+
+ // Huffman decoders for literal/length, distance.
+ h1, h2 huffmanDecoder
+
+ // Length arrays used to define Huffman codes.
+ bits *[maxNumLit + maxNumDist]int
+ codebits *[numCodes]int
+
+ // Output history, buffer.
+ dict dictDecoder
+
+ // Temporary buffer (avoids repeated allocation).
+ buf [4]byte
+
+ // Next step in the decompression,
+ // and decompression state.
+ step func(*decompressor)
+ stepState int
+ final bool
+ err error
+ toRead []byte
+ hl, hd *huffmanDecoder
+ copyLen int
+ copyDist int
+}
+
+func (f *decompressor) nextBlock() {
+ for f.nb < 1+2 {
+ if f.err = f.moreBits(); f.err != nil {
+ return
+ }
+ }
+ f.final = f.b&1 == 1
+ f.b >>= 1
+ typ := f.b & 3
+ f.b >>= 2
+ f.nb -= 1 + 2
+ switch typ {
+ case 0:
+ f.dataBlock()
+ case 1:
+ // compressed, fixed Huffman tables
+ f.hl = &fixedHuffmanDecoder
+ f.hd = nil
+ f.huffmanBlock()
+ case 2:
+ // compressed, dynamic Huffman tables
+ if f.err = f.readHuffman(); f.err != nil {
+ break
+ }
+ f.hl = &f.h1
+ f.hd = &f.h2
+ f.huffmanBlock()
+ default:
+ // 3 is reserved.
+ f.err = CorruptInputError(f.roffset)
+ }
+}
+
+func (f *decompressor) Read(b []byte) (int, error) {
+ for {
+ if len(f.toRead) > 0 {
+ n := copy(b, f.toRead)
+ f.toRead = f.toRead[n:]
+ if len(f.toRead) == 0 {
+ return n, f.err
+ }
+ return n, nil
+ }
+ if f.err != nil {
+ return 0, f.err
+ }
+ f.step(f)
+ if f.err != nil && len(f.toRead) == 0 {
+ f.toRead = f.dict.readFlush() // Flush what's left in case of error
+ }
+ }
+}
+
+func (f *decompressor) Close() error {
+ if f.err == io.EOF {
+ return nil
+ }
+ return f.err
+}
+
+// RFC 1951 section 3.2.7.
+// Compression with dynamic Huffman codes
+
+var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
+
+func (f *decompressor) readHuffman() error {
+ // HLIT[5], HDIST[5], HCLEN[4].
+ for f.nb < 5+5+4 {
+ if err := f.moreBits(); err != nil {
+ return err
+ }
+ }
+ nlit := int(f.b&0x1F) + 257
+ if nlit > maxNumLit {
+ return CorruptInputError(f.roffset)
+ }
+ f.b >>= 5
+ ndist := int(f.b&0x1F) + 1
+ if ndist > maxNumDist {
+ return CorruptInputError(f.roffset)
+ }
+ f.b >>= 5
+ nclen := int(f.b&0xF) + 4
+ // numCodes is 19, so nclen is always valid.
+ f.b >>= 4
+ f.nb -= 5 + 5 + 4
+
+ // (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.
+ for i := 0; i < nclen; i++ {
+ for f.nb < 3 {
+ if err := f.moreBits(); err != nil {
+ return err
+ }
+ }
+ f.codebits[codeOrder[i]] = int(f.b & 0x7)
+ f.b >>= 3
+ f.nb -= 3
+ }
+ for i := nclen; i < len(codeOrder); i++ {
+ f.codebits[codeOrder[i]] = 0
+ }
+ if !f.h1.init(f.codebits[0:]) {
+ return CorruptInputError(f.roffset)
+ }
+
+ // HLIT + 257 code lengths, HDIST + 1 code lengths,
+ // using the code length Huffman code.
+ for i, n := 0, nlit+ndist; i < n; {
+ x, err := f.huffSym(&f.h1)
+ if err != nil {
+ return err
+ }
+ if x < 16 {
+ // Actual length.
+ f.bits[i] = x
+ i++
+ continue
+ }
+ // Repeat previous length or zero.
+ var rep int
+ var nb uint
+ var b int
+ switch x {
+ default:
+ return InternalError("unexpected length code")
+ case 16:
+ rep = 3
+ nb = 2
+ if i == 0 {
+ return CorruptInputError(f.roffset)
+ }
+ b = f.bits[i-1]
+ case 17:
+ rep = 3
+ nb = 3
+ b = 0
+ case 18:
+ rep = 11
+ nb = 7
+ b = 0
+ }
+ for f.nb < nb {
+ if err := f.moreBits(); err != nil {
+ return err
+ }
+ }
+ rep += int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ if i+rep > n {
+ return CorruptInputError(f.roffset)
+ }
+ for j := 0; j < rep; j++ {
+ f.bits[i] = b
+ i++
+ }
+ }
+
+ if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {
+ return CorruptInputError(f.roffset)
+ }
+
+ // As an optimization, we can initialize the min bits to read at a time
+ // for the HLIT tree to the length of the EOB marker since we know that
+ // every block must terminate with one. This preserves the property that
+ // we never read any extra bytes after the end of the DEFLATE stream.
+ if f.h1.min < f.bits[endBlockMarker] {
+ f.h1.min = f.bits[endBlockMarker]
+ }
+
+ return nil
+}
+
+// Decode a single Huffman block from f.
+// hl and hd are the Huffman states for the lit/length values
+// and the distance values, respectively. If hd == nil, using the
+// fixed distance encoding associated with fixed Huffman blocks.
+func (f *decompressor) huffmanBlock() {
+ const (
+ stateInit = iota // Zero value must be stateInit
+ stateDict
+ )
+
+ switch f.stepState {
+ case stateInit:
+ goto readLiteral
+ case stateDict:
+ goto copyHistory
+ }
+
+readLiteral:
+ // Read literal and/or (length, distance) according to RFC section 3.2.3.
+ {
+ v, err := f.huffSym(f.hl)
+ if err != nil {
+ f.err = err
+ return
+ }
+ var n uint // number of bits extra
+ var length int
+ switch {
+ case v < 256:
+ f.dict.writeByte(byte(v))
+ if f.dict.availWrite() == 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBlock
+ f.stepState = stateInit
+ return
+ }
+ goto readLiteral
+ case v == 256:
+ f.finishBlock()
+ return
+ // otherwise, reference to older data
+ case v < 265:
+ length = v - (257 - 3)
+ n = 0
+ case v < 269:
+ length = v*2 - (265*2 - 11)
+ n = 1
+ case v < 273:
+ length = v*4 - (269*4 - 19)
+ n = 2
+ case v < 277:
+ length = v*8 - (273*8 - 35)
+ n = 3
+ case v < 281:
+ length = v*16 - (277*16 - 67)
+ n = 4
+ case v < 285:
+ length = v*32 - (281*32 - 131)
+ n = 5
+ case v < maxNumLit:
+ length = 258
+ n = 0
+ default:
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ if n > 0 {
+ for f.nb < n {
+ if err = f.moreBits(); err != nil {
+ f.err = err
+ return
+ }
+ }
+ length += int(f.b & uint32(1<<n-1))
+ f.b >>= n
+ f.nb -= n
+ }
+
+ var dist int
+ if f.hd == nil {
+ for f.nb < 5 {
+ if err = f.moreBits(); err != nil {
+ f.err = err
+ return
+ }
+ }
+ dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3)))
+ f.b >>= 5
+ f.nb -= 5
+ } else {
+ if dist, err = f.huffSym(f.hd); err != nil {
+ f.err = err
+ return
+ }
+ }
+
+ switch {
+ case dist < 4:
+ dist++
+ case dist < maxNumDist:
+ nb := uint(dist-2) >> 1
+ // have 1 bit in bottom of dist, need nb more.
+ extra := (dist & 1) << nb
+ for f.nb < nb {
+ if err = f.moreBits(); err != nil {
+ f.err = err
+ return
+ }
+ }
+ extra |= int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ dist = 1<<(nb+1) + 1 + extra
+ default:
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ // No check on length; encoding can be prescient.
+ if dist > f.dict.histSize() {
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ f.copyLen, f.copyDist = length, dist
+ goto copyHistory
+ }
+
+copyHistory:
+ // Perform a backwards copy according to RFC section 3.2.3.
+ {
+ cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen)
+ if cnt == 0 {
+ cnt = f.dict.writeCopy(f.copyDist, f.copyLen)
+ }
+ f.copyLen -= cnt
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBlock // We need to continue this work
+ f.stepState = stateDict
+ return
+ }
+ goto readLiteral
+ }
+}
+
+// Copy a single uncompressed data block from input to output.
+func (f *decompressor) dataBlock() {
+ // Uncompressed.
+ // Discard current half-byte.
+ f.nb = 0
+ f.b = 0
+
+ // Length then ones-complement of length.
+ nr, err := io.ReadFull(f.r, f.buf[0:4])
+ f.roffset += int64(nr)
+ if err != nil {
+ f.err = noEOF(err)
+ return
+ }
+ n := int(f.buf[0]) | int(f.buf[1])<<8
+ nn := int(f.buf[2]) | int(f.buf[3])<<8
+ if uint16(nn) != uint16(^n) {
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ if n == 0 {
+ f.toRead = f.dict.readFlush()
+ f.finishBlock()
+ return
+ }
+
+ f.copyLen = n
+ f.copyData()
+}
+
+// copyData copies f.copyLen bytes from the underlying reader into f.hist.
+// It pauses for reads when f.hist is full.
+func (f *decompressor) copyData() {
+ buf := f.dict.writeSlice()
+ if len(buf) > f.copyLen {
+ buf = buf[:f.copyLen]
+ }
+
+ cnt, err := io.ReadFull(f.r, buf)
+ f.roffset += int64(cnt)
+ f.copyLen -= cnt
+ f.dict.writeMark(cnt)
+ if err != nil {
+ f.err = noEOF(err)
+ return
+ }
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).copyData
+ return
+ }
+ f.finishBlock()
+}
+
+func (f *decompressor) finishBlock() {
+ if f.final {
+ if f.dict.availRead() > 0 {
+ f.toRead = f.dict.readFlush()
+ }
+ f.err = io.EOF
+ }
+ f.step = (*decompressor).nextBlock
+}
+
+// noEOF returns err, unless err == io.EOF, in which case it returns io.ErrUnexpectedEOF.
+func noEOF(e error) error {
+ if e == io.EOF {
+ return io.ErrUnexpectedEOF
+ }
+ return e
+}
+
+func (f *decompressor) moreBits() error {
+ c, err := f.r.ReadByte()
+ if err != nil {
+ return noEOF(err)
+ }
+ f.roffset++
+ f.b |= uint32(c) << f.nb
+ f.nb += 8
+ return nil
+}
+
+// Read the next Huffman-encoded symbol from f according to h.
+func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {
+ // Since a huffmanDecoder can be empty or be composed of a degenerate tree
+ // with single element, huffSym must error on these two edge cases. In both
+ // cases, the chunks slice will be 0 for the invalid sequence, leading it
+ // satisfy the n == 0 check below.
+ n := uint(h.min)
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
+ // but is smart enough to keep local variables in registers, so use nb and b,
+ // inline call to moreBits and reassign b,nb back to f on return.
+ nb, b := f.nb, f.b
+ for {
+ for nb < n {
+ c, err := f.r.ReadByte()
+ if err != nil {
+ f.b = b
+ f.nb = nb
+ return 0, noEOF(err)
+ }
+ f.roffset++
+ b |= uint32(c) << (nb & 31)
+ nb += 8
+ }
+ chunk := h.chunks[b&(huffmanNumChunks-1)]
+ n = uint(chunk & huffmanCountMask)
+ if n > huffmanChunkBits {
+ chunk = h.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&h.linkMask]
+ n = uint(chunk & huffmanCountMask)
+ }
+ if n <= nb {
+ if n == 0 {
+ f.b = b
+ f.nb = nb
+ f.err = CorruptInputError(f.roffset)
+ return 0, f.err
+ }
+ f.b = b >> (n & 31)
+ f.nb = nb - n
+ return int(chunk >> huffmanValueShift), nil
+ }
+ }
+}
+
+func (f *decompressor) makeReader(r io.Reader) {
+ if rr, ok := r.(Reader); ok {
+ f.rBuf = nil
+ f.r = rr
+ return
+ }
+ // Reuse rBuf if possible. Invariant: rBuf is always created (and owned) by decompressor.
+ if f.rBuf != nil {
+ f.rBuf.Reset(r)
+ } else {
+ // bufio.NewReader will not return r, as r does not implement flate.Reader, so it is not bufio.Reader.
+ f.rBuf = bufio.NewReader(r)
+ }
+ f.r = f.rBuf
+}
+
+func fixedHuffmanDecoderInit() {
+ fixedOnce.Do(func() {
+ // These come from the RFC section 3.2.6.
+ var bits [288]int
+ for i := 0; i < 144; i++ {
+ bits[i] = 8
+ }
+ for i := 144; i < 256; i++ {
+ bits[i] = 9
+ }
+ for i := 256; i < 280; i++ {
+ bits[i] = 7
+ }
+ for i := 280; i < 288; i++ {
+ bits[i] = 8
+ }
+ fixedHuffmanDecoder.init(bits[:])
+ })
+}
+
+func (f *decompressor) Reset(r io.Reader, dict []byte) error {
+ *f = decompressor{
+ rBuf: f.rBuf,
+ bits: f.bits,
+ codebits: f.codebits,
+ dict: f.dict,
+ step: (*decompressor).nextBlock,
+ }
+ f.makeReader(r)
+ f.dict.init(maxMatchOffset, dict)
+ return nil
+}
+
+// NewReader returns a new ReadCloser that can be used
+// to read the uncompressed version of r.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+// The reader returns io.EOF after the final block in the DEFLATE stream has
+// been encountered. Any trailing data after the final block is ignored.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReader(r io.Reader) io.ReadCloser {
+ fixedHuffmanDecoderInit()
+
+ var f decompressor
+ f.makeReader(r)
+ f.bits = new([maxNumLit + maxNumDist]int)
+ f.codebits = new([numCodes]int)
+ f.step = (*decompressor).nextBlock
+ f.dict.init(maxMatchOffset, nil)
+ return &f
+}
+
+// NewReaderDict is like NewReader but initializes the reader
+// with a preset dictionary. The returned Reader behaves as if
+// the uncompressed data stream started with the given dictionary,
+// which has already been read. NewReaderDict is typically used
+// to read data compressed by NewWriterDict.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser {
+ fixedHuffmanDecoderInit()
+
+ var f decompressor
+ f.makeReader(r)
+ f.bits = new([maxNumLit + maxNumDist]int)
+ f.codebits = new([numCodes]int)
+ f.step = (*decompressor).nextBlock
+ f.dict.init(maxMatchOffset, dict)
+ return &f
+}
diff --git a/src/compress/flate/inflate_test.go b/src/compress/flate/inflate_test.go
new file mode 100644
index 0000000..28a0122
--- /dev/null
+++ b/src/compress/flate/inflate_test.go
@@ -0,0 +1,137 @@
+// Copyright 2014 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 flate
+
+import (
+ "bufio"
+ "bytes"
+ "io"
+ "strings"
+ "testing"
+)
+
+func TestReset(t *testing.T) {
+ ss := []string{
+ "lorem ipsum izzle fo rizzle",
+ "the quick brown fox jumped over",
+ }
+
+ deflated := make([]bytes.Buffer, 2)
+ for i, s := range ss {
+ w, _ := NewWriter(&deflated[i], 1)
+ w.Write([]byte(s))
+ w.Close()
+ }
+
+ inflated := make([]bytes.Buffer, 2)
+
+ f := NewReader(&deflated[0])
+ io.Copy(&inflated[0], f)
+ f.(Resetter).Reset(&deflated[1], nil)
+ io.Copy(&inflated[1], f)
+ f.Close()
+
+ for i, s := range ss {
+ if s != inflated[i].String() {
+ t.Errorf("inflated[%d]:\ngot %q\nwant %q", i, inflated[i], s)
+ }
+ }
+}
+
+func TestReaderTruncated(t *testing.T) {
+ vectors := []struct{ input, output string }{
+ {"\x00", ""},
+ {"\x00\f", ""},
+ {"\x00\f\x00", ""},
+ {"\x00\f\x00\xf3\xff", ""},
+ {"\x00\f\x00\xf3\xffhello", "hello"},
+ {"\x00\f\x00\xf3\xffhello, world", "hello, world"},
+ {"\x02", ""},
+ {"\xf2H\xcd", "He"},
+ {"\xf2H͙0a\u0084\t", "Hel\x90\x90\x90\x90\x90"},
+ {"\xf2H͙0a\u0084\t\x00", "Hel\x90\x90\x90\x90\x90"},
+ }
+
+ for i, v := range vectors {
+ r := strings.NewReader(v.input)
+ zr := NewReader(r)
+ b, err := io.ReadAll(zr)
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("test %d, error mismatch: got %v, want io.ErrUnexpectedEOF", i, err)
+ }
+ if string(b) != v.output {
+ t.Errorf("test %d, output mismatch: got %q, want %q", i, b, v.output)
+ }
+ }
+}
+
+func TestResetDict(t *testing.T) {
+ dict := []byte("the lorem fox")
+ ss := []string{
+ "lorem ipsum izzle fo rizzle",
+ "the quick brown fox jumped over",
+ }
+
+ deflated := make([]bytes.Buffer, len(ss))
+ for i, s := range ss {
+ w, _ := NewWriterDict(&deflated[i], DefaultCompression, dict)
+ w.Write([]byte(s))
+ w.Close()
+ }
+
+ inflated := make([]bytes.Buffer, len(ss))
+
+ f := NewReader(nil)
+ for i := range inflated {
+ f.(Resetter).Reset(&deflated[i], dict)
+ io.Copy(&inflated[i], f)
+ }
+ f.Close()
+
+ for i, s := range ss {
+ if s != inflated[i].String() {
+ t.Errorf("inflated[%d]:\ngot %q\nwant %q", i, inflated[i], s)
+ }
+ }
+}
+
+func TestReaderReusesReaderBuffer(t *testing.T) {
+ encodedReader := bytes.NewReader([]byte{})
+ encodedNotByteReader := struct{ io.Reader }{encodedReader}
+
+ t.Run("BufferIsReused", func(t *testing.T) {
+ f := NewReader(encodedNotByteReader).(*decompressor)
+ bufioR, ok := f.r.(*bufio.Reader)
+ if !ok {
+ t.Fatalf("bufio.Reader should be created")
+ }
+ f.Reset(encodedNotByteReader, nil)
+ if bufioR != f.r {
+ t.Fatalf("bufio.Reader was not reused")
+ }
+ })
+ t.Run("BufferIsNotReusedWhenGotByteReader", func(t *testing.T) {
+ f := NewReader(encodedNotByteReader).(*decompressor)
+ if _, ok := f.r.(*bufio.Reader); !ok {
+ t.Fatalf("bufio.Reader should be created")
+ }
+ f.Reset(encodedReader, nil)
+ if f.r != encodedReader {
+ t.Fatalf("provided io.ByteReader should be used directly")
+ }
+ })
+ t.Run("BufferIsCreatedAfterByteReader", func(t *testing.T) {
+ for i, r := range []io.Reader{encodedReader, bufio.NewReader(encodedReader)} {
+ f := NewReader(r).(*decompressor)
+ if f.r != r {
+ t.Fatalf("provided io.ByteReader should be used directly, i=%d", i)
+ }
+ f.Reset(encodedNotByteReader, nil)
+ if _, ok := f.r.(*bufio.Reader); !ok {
+ t.Fatalf("bufio.Reader should be created, i=%d", i)
+ }
+ }
+ })
+}
diff --git a/src/compress/flate/reader_test.go b/src/compress/flate/reader_test.go
new file mode 100644
index 0000000..94610fb
--- /dev/null
+++ b/src/compress/flate/reader_test.go
@@ -0,0 +1,98 @@
+// Copyright 2012 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 flate
+
+import (
+ "bytes"
+ "io"
+ "os"
+ "runtime"
+ "strings"
+ "testing"
+)
+
+func TestNlitOutOfRange(t *testing.T) {
+ // Trying to decode this bogus flate data, which has a Huffman table
+ // with nlit=288, should not panic.
+ io.Copy(io.Discard, NewReader(strings.NewReader(
+ "\xfc\xfe\x36\xe7\x5e\x1c\xef\xb3\x55\x58\x77\xb6\x56\xb5\x43\xf4"+
+ "\x6f\xf2\xd2\xe6\x3d\x99\xa0\x85\x8c\x48\xeb\xf8\xda\x83\x04\x2a"+
+ "\x75\xc4\xf8\x0f\x12\x11\xb9\xb4\x4b\x09\xa0\xbe\x8b\x91\x4c")))
+}
+
+var suites = []struct{ name, file string }{
+ // Digits is the digits of the irrational number e. Its decimal representation
+ // does not repeat, but there are only 10 possible digits, so it should be
+ // reasonably compressible.
+ {"Digits", "../testdata/e.txt"},
+ // Newton is Isaac Newtons's educational text on Opticks.
+ {"Newton", "../../testdata/Isaac.Newton-Opticks.txt"},
+}
+
+func BenchmarkDecode(b *testing.B) {
+ doBench(b, func(b *testing.B, buf0 []byte, level, n int) {
+ b.ReportAllocs()
+ b.StopTimer()
+ b.SetBytes(int64(n))
+
+ compressed := new(bytes.Buffer)
+ w, err := NewWriter(compressed, level)
+ if err != nil {
+ b.Fatal(err)
+ }
+ for i := 0; i < n; i += len(buf0) {
+ if len(buf0) > n-i {
+ buf0 = buf0[:n-i]
+ }
+ io.Copy(w, bytes.NewReader(buf0))
+ }
+ w.Close()
+ buf1 := compressed.Bytes()
+ buf0, compressed, w = nil, nil, nil
+ runtime.GC()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ io.Copy(io.Discard, NewReader(bytes.NewReader(buf1)))
+ }
+ })
+}
+
+var levelTests = []struct {
+ name string
+ level int
+}{
+ {"Huffman", HuffmanOnly},
+ {"Speed", BestSpeed},
+ {"Default", DefaultCompression},
+ {"Compression", BestCompression},
+}
+
+var sizes = []struct {
+ name string
+ n int
+}{
+ {"1e4", 1e4},
+ {"1e5", 1e5},
+ {"1e6", 1e6},
+}
+
+func doBench(b *testing.B, f func(b *testing.B, buf []byte, level, n int)) {
+ for _, suite := range suites {
+ buf, err := os.ReadFile(suite.file)
+ if err != nil {
+ b.Fatal(err)
+ }
+ if len(buf) == 0 {
+ b.Fatalf("test file %q has no data", suite.file)
+ }
+ for _, l := range levelTests {
+ for _, s := range sizes {
+ b.Run(suite.name+"/"+l.name+"/"+s.name, func(b *testing.B) {
+ f(b, buf, l.level, s.n)
+ })
+ }
+ }
+ }
+}
diff --git a/src/compress/flate/testdata/huffman-null-max.dyn.expect b/src/compress/flate/testdata/huffman-null-max.dyn.expect
new file mode 100644
index 0000000..c081651
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-null-max.dyn.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-null-max.dyn.expect-noinput b/src/compress/flate/testdata/huffman-null-max.dyn.expect-noinput
new file mode 100644
index 0000000..c081651
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-null-max.dyn.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-null-max.golden b/src/compress/flate/testdata/huffman-null-max.golden
new file mode 100644
index 0000000..db422ca
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-null-max.golden
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-null-max.in b/src/compress/flate/testdata/huffman-null-max.in
new file mode 100644
index 0000000..5dfddf0
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-null-max.in
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-null-max.wb.expect b/src/compress/flate/testdata/huffman-null-max.wb.expect
new file mode 100644
index 0000000..c081651
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-null-max.wb.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-null-max.wb.expect-noinput b/src/compress/flate/testdata/huffman-null-max.wb.expect-noinput
new file mode 100644
index 0000000..c081651
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-null-max.wb.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-pi.dyn.expect b/src/compress/flate/testdata/huffman-pi.dyn.expect
new file mode 100644
index 0000000..e4396ac
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-pi.dyn.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-pi.dyn.expect-noinput b/src/compress/flate/testdata/huffman-pi.dyn.expect-noinput
new file mode 100644
index 0000000..e4396ac
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-pi.dyn.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-pi.golden b/src/compress/flate/testdata/huffman-pi.golden
new file mode 100644
index 0000000..23d8f7f
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-pi.golden
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-pi.in b/src/compress/flate/testdata/huffman-pi.in
new file mode 100644
index 0000000..efaed43
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-pi.in
@@ -0,0 +1 @@
+3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420198938095257201065485863278865936153381827968230301952035301852968995773622599413891249721775283479131515574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012858361603563707660104710181942955596198946767837449448255379774726847104047534646208046684259069491293313677028989152104752162056966024058038150193511253382430035587640247496473263914199272604269922796782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955321165344987202755960236480665499119881834797753566369807426542527862551818417574672890977772793800081647060016145249192173217214772350141441973568548161361157352552133475741849468438523323907394143334547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383827967976681454100953883786360950680064225125205117392984896084128488626945604241965285022210661186306744278622039194945047123713786960956364371917287467764657573962413890865832645995813390478027590099465764078951269468398352595709825822620522489407726719478268482601476990902640136394437455305068203496252451749399651431429809190659250937221696461515709858387410597885959772975498930161753928468138268683868942774155991855925245953959431049972524680845987273644695848653836736222626099124608051243884390451244136549762780797715691435997700129616089441694868555848406353422072225828488648158456028506016842739452267467678895252138522549954666727823986456596116354886230577456498035593634568174324112515076069479451096596094025228879710893145669136867228748940560101503308617928680920874760917824938589009714909675985261365549781893129784821682998948722658804857564014270477555132379641451523746234364542858444795265867821051141354735739523113427166102135969536231442952484937187110145765403590279934403742007310578539062198387447808478489683321445713868751943506430218453191048481005370614680674919278191197939952061419663428754440643745123718192179998391015919561814675142691239748940907186494231961567945208095146550225231603881930142093762137855956638937787083039069792077346722182562599661501421503068038447734549202605414665925201497442850732518666002132434088190710486331734649651453905796268561005508106658796998163574736384052571459102897064140110971206280439039759515677157700420337869936007230558763176359421873125147120532928191826186125867321579198414848829164470609575270695722091756711672291098169091528017350671274858322287183520935396572512108357915136988209144421006751033467110314126711136990865851639831501970165151168517143765761835155650884909989859982387345528331635507647918535893226185489632132933089857064204675259070915481416549859461637180 \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-pi.wb.expect b/src/compress/flate/testdata/huffman-pi.wb.expect
new file mode 100644
index 0000000..e4396ac
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-pi.wb.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-pi.wb.expect-noinput b/src/compress/flate/testdata/huffman-pi.wb.expect-noinput
new file mode 100644
index 0000000..e4396ac
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-pi.wb.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-1k.dyn.expect b/src/compress/flate/testdata/huffman-rand-1k.dyn.expect
new file mode 100644
index 0000000..09dc798
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-1k.dyn.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-1k.dyn.expect-noinput b/src/compress/flate/testdata/huffman-rand-1k.dyn.expect-noinput
new file mode 100644
index 0000000..0c24742
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-1k.dyn.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-1k.golden b/src/compress/flate/testdata/huffman-rand-1k.golden
new file mode 100644
index 0000000..09dc798
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-1k.golden
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-1k.in b/src/compress/flate/testdata/huffman-rand-1k.in
new file mode 100644
index 0000000..ce038eb
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-1k.in
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-1k.wb.expect b/src/compress/flate/testdata/huffman-rand-1k.wb.expect
new file mode 100644
index 0000000..09dc798
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-1k.wb.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-1k.wb.expect-noinput b/src/compress/flate/testdata/huffman-rand-1k.wb.expect-noinput
new file mode 100644
index 0000000..0c24742
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-1k.wb.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-limit.dyn.expect b/src/compress/flate/testdata/huffman-rand-limit.dyn.expect
new file mode 100644
index 0000000..2d65279
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-limit.dyn.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-limit.dyn.expect-noinput b/src/compress/flate/testdata/huffman-rand-limit.dyn.expect-noinput
new file mode 100644
index 0000000..2d65279
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-limit.dyn.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-limit.golden b/src/compress/flate/testdata/huffman-rand-limit.golden
new file mode 100644
index 0000000..57e5932
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-limit.golden
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-limit.in b/src/compress/flate/testdata/huffman-rand-limit.in
new file mode 100644
index 0000000..fb5b1be
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-limit.in
@@ -0,0 +1,4 @@
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ø‹–vH
+…”%€¯Âþè ë†É·ÅÞê}‹ç>ÚßÿlsÞÌçmIGH°èžò1YÞ4´[åà 0ˆ[|]o#©
+¼-#¾Ùíul™ßýpfæîÙ±žnƒYÕÔ€Y˜w‰C8ɯ02š F=gn×ržN!OÆàÔ{¥ö›kÜ*“w(ý´bÚ ç«kQC9/ ’lu>ô5ýC.÷¤uÚê›
diff --git a/src/compress/flate/testdata/huffman-rand-limit.wb.expect b/src/compress/flate/testdata/huffman-rand-limit.wb.expect
new file mode 100644
index 0000000..881e59c
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-limit.wb.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-limit.wb.expect-noinput b/src/compress/flate/testdata/huffman-rand-limit.wb.expect-noinput
new file mode 100644
index 0000000..881e59c
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-limit.wb.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-max.golden b/src/compress/flate/testdata/huffman-rand-max.golden
new file mode 100644
index 0000000..47d53c8
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-max.golden
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-rand-max.in b/src/compress/flate/testdata/huffman-rand-max.in
new file mode 100644
index 0000000..8418633
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-rand-max.in
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-shifts.dyn.expect b/src/compress/flate/testdata/huffman-shifts.dyn.expect
new file mode 100644
index 0000000..7812c1c
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-shifts.dyn.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-shifts.dyn.expect-noinput b/src/compress/flate/testdata/huffman-shifts.dyn.expect-noinput
new file mode 100644
index 0000000..7812c1c
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-shifts.dyn.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-shifts.golden b/src/compress/flate/testdata/huffman-shifts.golden
new file mode 100644
index 0000000..f513377
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-shifts.golden
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-shifts.in b/src/compress/flate/testdata/huffman-shifts.in
new file mode 100644
index 0000000..7c7a50d
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-shifts.in
@@ -0,0 +1,2 @@
+101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010
+232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323 \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-shifts.wb.expect b/src/compress/flate/testdata/huffman-shifts.wb.expect
new file mode 100644
index 0000000..7812c1c
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-shifts.wb.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-shifts.wb.expect-noinput b/src/compress/flate/testdata/huffman-shifts.wb.expect-noinput
new file mode 100644
index 0000000..7812c1c
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-shifts.wb.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-text-shift.dyn.expect b/src/compress/flate/testdata/huffman-text-shift.dyn.expect
new file mode 100644
index 0000000..71ce3ae
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text-shift.dyn.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-text-shift.dyn.expect-noinput b/src/compress/flate/testdata/huffman-text-shift.dyn.expect-noinput
new file mode 100644
index 0000000..71ce3ae
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text-shift.dyn.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-text-shift.golden b/src/compress/flate/testdata/huffman-text-shift.golden
new file mode 100644
index 0000000..ff02311
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text-shift.golden
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-text-shift.in b/src/compress/flate/testdata/huffman-text-shift.in
new file mode 100644
index 0000000..cc5c3ad
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text-shift.in
@@ -0,0 +1,14 @@
+//Copyright2009ThGoAuthor.Allrightrrvd.
+//UofthiourccodigovrndbyBSD-tyl
+//licnthtcnbfoundinthLICENSEfil.
+
+pckgmin
+
+import"o"
+
+funcmin(){
+ vrb=mk([]byt,65535)
+ f,_:=o.Crt("huffmn-null-mx.in")
+ f.Writ(b)
+}
+ABCDEFGHIJKLMNOPQRSTUVXxyz!"#¤%&/?" \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-text-shift.wb.expect b/src/compress/flate/testdata/huffman-text-shift.wb.expect
new file mode 100644
index 0000000..71ce3ae
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text-shift.wb.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-text-shift.wb.expect-noinput b/src/compress/flate/testdata/huffman-text-shift.wb.expect-noinput
new file mode 100644
index 0000000..71ce3ae
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text-shift.wb.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-text.dyn.expect b/src/compress/flate/testdata/huffman-text.dyn.expect
new file mode 100644
index 0000000..d448727
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text.dyn.expect
@@ -0,0 +1 @@
+Ë_Kó0Åñëò½ê`KÇó0AasÄ›)^ˆHšþ²„¥IÉŸbß»¬—_>ç4 a˜¢=›Œ›Í-^ á1`_² 1 ìÃÌ ‘Å‘:ÁYÓà-‚F66!…A…Ž`Îa¤è©C;Aâþô°Nyr4ßœUä!™¡¤GKСøÖ#ÂóÓáør:B[G‚3Ω.òLè¥õ׶ýbFRuM]¼š­^⇳Å(#ZìÐË ÕŸí”i…›íöÿvÉÙB¯ð…»B‡H2S]™¢u/ýÚçÖ½üÖWóT¼G›©n—œýrö \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-text.dyn.expect-noinput b/src/compress/flate/testdata/huffman-text.dyn.expect-noinput
new file mode 100644
index 0000000..d448727
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text.dyn.expect-noinput
@@ -0,0 +1 @@
+Ë_Kó0Åñëò½ê`KÇó0AasÄ›)^ˆHšþ²„¥IÉŸbß»¬—_>ç4 a˜¢=›Œ›Í-^ á1`_² 1 ìÃÌ ‘Å‘:ÁYÓà-‚F66!…A…Ž`Îa¤è©C;Aâþô°Nyr4ßœUä!™¡¤GKСøÖ#ÂóÓáør:B[G‚3Ω.òLè¥õ׶ýbFRuM]¼š­^⇳Å(#ZìÐË ÕŸí”i…›íöÿvÉÙB¯ð…»B‡H2S]™¢u/ýÚçÖ½üÖWóT¼G›©n—œýrö \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-text.golden b/src/compress/flate/testdata/huffman-text.golden
new file mode 100644
index 0000000..6d34c61
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text.golden
@@ -0,0 +1,3 @@
+ÀAKó0ðóx¾ÃŸžZØÚñ¾LPØaÎ!‚x™âADÒöI–&#I‹EüîþšÇp]¢LÆ¿íö¯Fðp˜² 1Õ88‡h“¢$‰³ô5SÓà- ‚F66!…)v‚.ô›0„Y¢—í…ûóÃ&åÅ SÓÀÙN|d£2:åÑ
+t˜|ë‘àùéxz9Ÿ ­“š‰éªº‹£²ž‰ÉŽ×3Š
+&&=ù£²¾¬ðôšUD‹=Fu‘òã³]²¬q³ÛýßUL+½Æîö©>FQYÊÂLZÊoüäÜfTßµõEÅ´Òõ{´Yʶbúeú \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-text.in b/src/compress/flate/testdata/huffman-text.in
new file mode 100644
index 0000000..73398b9
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text.in
@@ -0,0 +1,13 @@
+// Copyright 2009 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 main
+
+import "os"
+
+func main() {
+ var b = make([]byte, 65535)
+ f, _ := os.Create("huffman-null-max.in")
+ f.Write(b)
+}
diff --git a/src/compress/flate/testdata/huffman-text.wb.expect b/src/compress/flate/testdata/huffman-text.wb.expect
new file mode 100644
index 0000000..d448727
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text.wb.expect
@@ -0,0 +1 @@
+Ë_Kó0Åñëò½ê`KÇó0AasÄ›)^ˆHšþ²„¥IÉŸbß»¬—_>ç4 a˜¢=›Œ›Í-^ á1`_² 1 ìÃÌ ‘Å‘:ÁYÓà-‚F66!…A…Ž`Îa¤è©C;Aâþô°Nyr4ßœUä!™¡¤GKСøÖ#ÂóÓáør:B[G‚3Ω.òLè¥õ׶ýbFRuM]¼š­^⇳Å(#ZìÐË ÕŸí”i…›íöÿvÉÙB¯ð…»B‡H2S]™¢u/ýÚçÖ½üÖWóT¼G›©n—œýrö \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-text.wb.expect-noinput b/src/compress/flate/testdata/huffman-text.wb.expect-noinput
new file mode 100644
index 0000000..d448727
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-text.wb.expect-noinput
@@ -0,0 +1 @@
+Ë_Kó0Åñëò½ê`KÇó0AasÄ›)^ˆHšþ²„¥IÉŸbß»¬—_>ç4 a˜¢=›Œ›Í-^ á1`_² 1 ìÃÌ ‘Å‘:ÁYÓà-‚F66!…A…Ž`Îa¤è©C;Aâþô°Nyr4ßœUä!™¡¤GKСøÖ#ÂóÓáør:B[G‚3Ω.òLè¥õ׶ýbFRuM]¼š­^⇳Å(#ZìÐË ÕŸí”i…›íöÿvÉÙB¯ð…»B‡H2S]™¢u/ýÚçÖ½üÖWóT¼G›©n—œýrö \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-zero.dyn.expect b/src/compress/flate/testdata/huffman-zero.dyn.expect
new file mode 100644
index 0000000..830348a
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-zero.dyn.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-zero.dyn.expect-noinput b/src/compress/flate/testdata/huffman-zero.dyn.expect-noinput
new file mode 100644
index 0000000..830348a
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-zero.dyn.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-zero.golden b/src/compress/flate/testdata/huffman-zero.golden
new file mode 100644
index 0000000..5abdbaf
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-zero.golden
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-zero.in b/src/compress/flate/testdata/huffman-zero.in
new file mode 100644
index 0000000..349be0e
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-zero.in
@@ -0,0 +1 @@
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file
diff --git a/src/compress/flate/testdata/huffman-zero.wb.expect b/src/compress/flate/testdata/huffman-zero.wb.expect
new file mode 100644
index 0000000..dbe401c
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-zero.wb.expect
Binary files differ
diff --git a/src/compress/flate/testdata/huffman-zero.wb.expect-noinput b/src/compress/flate/testdata/huffman-zero.wb.expect-noinput
new file mode 100644
index 0000000..dbe401c
--- /dev/null
+++ b/src/compress/flate/testdata/huffman-zero.wb.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/null-long-match.dyn.expect-noinput b/src/compress/flate/testdata/null-long-match.dyn.expect-noinput
new file mode 100644
index 0000000..8b92d9f
--- /dev/null
+++ b/src/compress/flate/testdata/null-long-match.dyn.expect-noinput
Binary files differ
diff --git a/src/compress/flate/testdata/null-long-match.wb.expect-noinput b/src/compress/flate/testdata/null-long-match.wb.expect-noinput
new file mode 100644
index 0000000..8b92d9f
--- /dev/null
+++ b/src/compress/flate/testdata/null-long-match.wb.expect-noinput
Binary files differ
diff --git a/src/compress/flate/token.go b/src/compress/flate/token.go
new file mode 100644
index 0000000..fc0e494
--- /dev/null
+++ b/src/compress/flate/token.go
@@ -0,0 +1,97 @@
+// Copyright 2009 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 flate
+
+const (
+ // 2 bits: type 0 = literal 1=EOF 2=Match 3=Unused
+ // 8 bits: xlength = length - MIN_MATCH_LENGTH
+ // 22 bits xoffset = offset - MIN_OFFSET_SIZE, or literal
+ lengthShift = 22
+ offsetMask = 1<<lengthShift - 1
+ typeMask = 3 << 30
+ literalType = 0 << 30
+ matchType = 1 << 30
+)
+
+// The length code for length X (MIN_MATCH_LENGTH <= X <= MAX_MATCH_LENGTH)
+// is lengthCodes[length - MIN_MATCH_LENGTH]
+var lengthCodes = [...]uint32{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8,
+ 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+ 13, 13, 13, 13, 14, 14, 14, 14, 15, 15,
+ 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17, 18, 18,
+ 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+ 19, 19, 19, 19, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 28,
+}
+
+var offsetCodes = [...]uint32{
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+}
+
+type token uint32
+
+// Convert a literal into a literal token.
+func literalToken(literal uint32) token { return token(literalType + literal) }
+
+// Convert a < xlength, xoffset > pair into a match token.
+func matchToken(xlength uint32, xoffset uint32) token {
+ return token(matchType + xlength<<lengthShift + xoffset)
+}
+
+// Returns the literal of a literal token.
+func (t token) literal() uint32 { return uint32(t - literalType) }
+
+// Returns the extra offset of a match token.
+func (t token) offset() uint32 { return uint32(t) & offsetMask }
+
+func (t token) length() uint32 { return uint32((t - matchType) >> lengthShift) }
+
+func lengthCode(len uint32) uint32 { return lengthCodes[len] }
+
+// Returns the offset code corresponding to a specific offset.
+func offsetCode(off uint32) uint32 {
+ if off < uint32(len(offsetCodes)) {
+ return offsetCodes[off]
+ }
+ if off>>7 < uint32(len(offsetCodes)) {
+ return offsetCodes[off>>7] + 14
+ }
+ return offsetCodes[off>>14] + 28
+}
diff --git a/src/compress/flate/writer_test.go b/src/compress/flate/writer_test.go
new file mode 100644
index 0000000..c413735
--- /dev/null
+++ b/src/compress/flate/writer_test.go
@@ -0,0 +1,237 @@
+// Copyright 2012 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 flate
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "math/rand"
+ "runtime"
+ "testing"
+)
+
+func BenchmarkEncode(b *testing.B) {
+ doBench(b, func(b *testing.B, buf0 []byte, level, n int) {
+ b.StopTimer()
+ b.SetBytes(int64(n))
+
+ buf1 := make([]byte, n)
+ for i := 0; i < n; i += len(buf0) {
+ if len(buf0) > n-i {
+ buf0 = buf0[:n-i]
+ }
+ copy(buf1[i:], buf0)
+ }
+ buf0 = nil
+ w, err := NewWriter(io.Discard, level)
+ if err != nil {
+ b.Fatal(err)
+ }
+ runtime.GC()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ w.Reset(io.Discard)
+ w.Write(buf1)
+ w.Close()
+ }
+ })
+}
+
+// errorWriter is a writer that fails after N writes.
+type errorWriter struct {
+ N int
+}
+
+func (e *errorWriter) Write(b []byte) (int, error) {
+ if e.N <= 0 {
+ return 0, io.ErrClosedPipe
+ }
+ e.N--
+ return len(b), nil
+}
+
+// Test if errors from the underlying writer is passed upwards.
+func TestWriteError(t *testing.T) {
+ t.Parallel()
+ buf := new(bytes.Buffer)
+ n := 65536
+ if !testing.Short() {
+ n *= 4
+ }
+ for i := 0; i < n; i++ {
+ fmt.Fprintf(buf, "asdasfasf%d%dfghfgujyut%dyutyu\n", i, i, i)
+ }
+ in := buf.Bytes()
+ // We create our own buffer to control number of writes.
+ copyBuffer := make([]byte, 128)
+ for l := 0; l < 10; l++ {
+ for fail := 1; fail <= 256; fail *= 2 {
+ // Fail after 'fail' writes
+ ew := &errorWriter{N: fail}
+ w, err := NewWriter(ew, l)
+ if err != nil {
+ t.Fatalf("NewWriter: level %d: %v", l, err)
+ }
+ n, err := io.CopyBuffer(w, struct{ io.Reader }{bytes.NewBuffer(in)}, copyBuffer)
+ if err == nil {
+ t.Fatalf("Level %d: Expected an error, writer was %#v", l, ew)
+ }
+ n2, err := w.Write([]byte{1, 2, 2, 3, 4, 5})
+ if n2 != 0 {
+ t.Fatal("Level", l, "Expected 0 length write, got", n)
+ }
+ if err == nil {
+ t.Fatal("Level", l, "Expected an error")
+ }
+ err = w.Flush()
+ if err == nil {
+ t.Fatal("Level", l, "Expected an error on flush")
+ }
+ err = w.Close()
+ if err == nil {
+ t.Fatal("Level", l, "Expected an error on close")
+ }
+
+ w.Reset(io.Discard)
+ n2, err = w.Write([]byte{1, 2, 3, 4, 5, 6})
+ if err != nil {
+ t.Fatal("Level", l, "Got unexpected error after reset:", err)
+ }
+ if n2 == 0 {
+ t.Fatal("Level", l, "Got 0 length write, expected > 0")
+ }
+ if testing.Short() {
+ return
+ }
+ }
+ }
+}
+
+// Test if two runs produce identical results
+// even when writing different sizes to the Writer.
+func TestDeterministic(t *testing.T) {
+ t.Parallel()
+ for i := 0; i <= 9; i++ {
+ t.Run(fmt.Sprint("L", i), func(t *testing.T) { testDeterministic(i, t) })
+ }
+ t.Run("LM2", func(t *testing.T) { testDeterministic(-2, t) })
+}
+
+func testDeterministic(i int, t *testing.T) {
+ t.Parallel()
+ // Test so much we cross a good number of block boundaries.
+ var length = maxStoreBlockSize*30 + 500
+ if testing.Short() {
+ length /= 10
+ }
+
+ // Create a random, but compressible stream.
+ rng := rand.New(rand.NewSource(1))
+ t1 := make([]byte, length)
+ for i := range t1 {
+ t1[i] = byte(rng.Int63() & 7)
+ }
+
+ // Do our first encode.
+ var b1 bytes.Buffer
+ br := bytes.NewBuffer(t1)
+ w, err := NewWriter(&b1, i)
+ if err != nil {
+ t.Fatal(err)
+ }
+ // Use a very small prime sized buffer.
+ cbuf := make([]byte, 787)
+ _, err = io.CopyBuffer(w, struct{ io.Reader }{br}, cbuf)
+ if err != nil {
+ t.Fatal(err)
+ }
+ w.Close()
+
+ // We choose a different buffer size,
+ // bigger than a maximum block, and also a prime.
+ var b2 bytes.Buffer
+ cbuf = make([]byte, 81761)
+ br2 := bytes.NewBuffer(t1)
+ w2, err := NewWriter(&b2, i)
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, err = io.CopyBuffer(w2, struct{ io.Reader }{br2}, cbuf)
+ if err != nil {
+ t.Fatal(err)
+ }
+ w2.Close()
+
+ b1b := b1.Bytes()
+ b2b := b2.Bytes()
+
+ if !bytes.Equal(b1b, b2b) {
+ t.Errorf("level %d did not produce deterministic result, result mismatch, len(a) = %d, len(b) = %d", i, len(b1b), len(b2b))
+ }
+}
+
+// TestDeflateFast_Reset will test that encoding is consistent
+// across a warparound of the table offset.
+// See https://github.com/golang/go/issues/34121
+func TestDeflateFast_Reset(t *testing.T) {
+ buf := new(bytes.Buffer)
+ n := 65536
+
+ for i := 0; i < n; i++ {
+ fmt.Fprintf(buf, "asdfasdfasdfasdf%d%dfghfgujyut%dyutyu\n", i, i, i)
+ }
+ // This is specific to level 1.
+ const level = 1
+ in := buf.Bytes()
+ offset := 1
+ if testing.Short() {
+ offset = 256
+ }
+
+ // We do an encode with a clean buffer to compare.
+ var want bytes.Buffer
+ w, err := NewWriter(&want, level)
+ if err != nil {
+ t.Fatalf("NewWriter: level %d: %v", level, err)
+ }
+
+ // Output written 3 times.
+ w.Write(in)
+ w.Write(in)
+ w.Write(in)
+ w.Close()
+
+ for ; offset <= 256; offset *= 2 {
+ w, err := NewWriter(io.Discard, level)
+ if err != nil {
+ t.Fatalf("NewWriter: level %d: %v", level, err)
+ }
+
+ // Reset until we are right before the wraparound.
+ // Each reset adds maxMatchOffset to the offset.
+ for i := 0; i < (bufferReset-len(in)-offset-maxMatchOffset)/maxMatchOffset; i++ {
+ // skip ahead to where we are close to wrap around...
+ w.d.reset(nil)
+ }
+ var got bytes.Buffer
+ w.Reset(&got)
+
+ // Write 3 times, close.
+ for i := 0; i < 3; i++ {
+ _, err = w.Write(in)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+ err = w.Close()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(got.Bytes(), want.Bytes()) {
+ t.Fatalf("output did not match at wraparound, len(want) = %d, len(got) = %d", want.Len(), got.Len())
+ }
+ }
+}
diff --git a/src/compress/gzip/example_test.go b/src/compress/gzip/example_test.go
new file mode 100644
index 0000000..1ba4080
--- /dev/null
+++ b/src/compress/gzip/example_test.go
@@ -0,0 +1,218 @@
+// Copyright 2016 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 gzip_test
+
+import (
+ "bytes"
+ "compress/gzip"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "net/http/httptest"
+ "os"
+ "strings"
+ "time"
+)
+
+func Example_writerReader() {
+ var buf bytes.Buffer
+ zw := gzip.NewWriter(&buf)
+
+ // Setting the Header fields is optional.
+ zw.Name = "a-new-hope.txt"
+ zw.Comment = "an epic space opera by George Lucas"
+ zw.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
+
+ _, err := zw.Write([]byte("A long time ago in a galaxy far, far away..."))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ if err := zw.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ zr, err := gzip.NewReader(&buf)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())
+
+ if _, err := io.Copy(os.Stdout, zr); err != nil {
+ log.Fatal(err)
+ }
+
+ if err := zr.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // Name: a-new-hope.txt
+ // Comment: an epic space opera by George Lucas
+ // ModTime: 1977-05-25 00:00:00 +0000 UTC
+ //
+ // A long time ago in a galaxy far, far away...
+}
+
+func ExampleReader_Multistream() {
+ var buf bytes.Buffer
+ zw := gzip.NewWriter(&buf)
+
+ var files = []struct {
+ name string
+ comment string
+ modTime time.Time
+ data string
+ }{
+ {"file-1.txt", "file-header-1", time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC), "Hello Gophers - 1"},
+ {"file-2.txt", "file-header-2", time.Date(2007, time.March, 2, 4, 5, 6, 1, time.UTC), "Hello Gophers - 2"},
+ }
+
+ for _, file := range files {
+ zw.Name = file.name
+ zw.Comment = file.comment
+ zw.ModTime = file.modTime
+
+ if _, err := zw.Write([]byte(file.data)); err != nil {
+ log.Fatal(err)
+ }
+
+ if err := zw.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ zw.Reset(&buf)
+ }
+
+ zr, err := gzip.NewReader(&buf)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for {
+ zr.Multistream(false)
+ fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())
+
+ if _, err := io.Copy(os.Stdout, zr); err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Print("\n\n")
+
+ err = zr.Reset(&buf)
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ if err := zr.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // Name: file-1.txt
+ // Comment: file-header-1
+ // ModTime: 2006-02-01 03:04:05 +0000 UTC
+ //
+ // Hello Gophers - 1
+ //
+ // Name: file-2.txt
+ // Comment: file-header-2
+ // ModTime: 2007-03-02 04:05:06 +0000 UTC
+ //
+ // Hello Gophers - 2
+}
+
+func Example_compressingReader() {
+ // This is an example of writing a compressing reader.
+ // This can be useful for an HTTP client body, as shown.
+
+ const testdata = "the data to be compressed"
+
+ // This HTTP handler is just for testing purposes.
+ handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+ zr, err := gzip.NewReader(req.Body)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Just output the data for the example.
+ if _, err := io.Copy(os.Stdout, zr); err != nil {
+ log.Fatal(err)
+ }
+ })
+ ts := httptest.NewServer(handler)
+ defer ts.Close()
+
+ // The remainder is the example code.
+
+ // The data we want to compress, as an io.Reader
+ dataReader := strings.NewReader(testdata)
+
+ // bodyReader is the body of the HTTP request, as an io.Reader.
+ // httpWriter is the body of the HTTP request, as an io.Writer.
+ bodyReader, httpWriter := io.Pipe()
+
+ // Make sure that bodyReader is always closed, so that the
+ // goroutine below will always exit.
+ defer bodyReader.Close()
+
+ // gzipWriter compresses data to httpWriter.
+ gzipWriter := gzip.NewWriter(httpWriter)
+
+ // errch collects any errors from the writing goroutine.
+ errch := make(chan error, 1)
+
+ go func() {
+ defer close(errch)
+ sentErr := false
+ sendErr := func(err error) {
+ if !sentErr {
+ errch <- err
+ sentErr = true
+ }
+ }
+
+ // Copy our data to gzipWriter, which compresses it to
+ // gzipWriter, which feeds it to bodyReader.
+ if _, err := io.Copy(gzipWriter, dataReader); err != nil && err != io.ErrClosedPipe {
+ sendErr(err)
+ }
+ if err := gzipWriter.Close(); err != nil && err != io.ErrClosedPipe {
+ sendErr(err)
+ }
+ if err := httpWriter.Close(); err != nil && err != io.ErrClosedPipe {
+ sendErr(err)
+ }
+ }()
+
+ // Send an HTTP request to the test server.
+ req, err := http.NewRequest("PUT", ts.URL, bodyReader)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Note that passing req to http.Client.Do promises that it
+ // will close the body, in this case bodyReader.
+ resp, err := ts.Client().Do(req)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Check whether there was an error compressing the data.
+ if err := <-errch; err != nil {
+ log.Fatal(err)
+ }
+
+ // For this example we don't care about the response.
+ resp.Body.Close()
+
+ // Output: the data to be compressed
+}
diff --git a/src/compress/gzip/fuzz_test.go b/src/compress/gzip/fuzz_test.go
new file mode 100644
index 0000000..80d803c
--- /dev/null
+++ b/src/compress/gzip/fuzz_test.go
@@ -0,0 +1,92 @@
+// Copyright 2021 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 gzip
+
+import (
+ "bytes"
+ "encoding/base64"
+ "io"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+func FuzzReader(f *testing.F) {
+ inp := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
+ for _, level := range []int{BestSpeed, BestCompression, DefaultCompression, HuffmanOnly} {
+ b := bytes.NewBuffer(nil)
+ w, err := NewWriterLevel(b, level)
+ if err != nil {
+ f.Fatalf("failed to construct writer: %s", err)
+ }
+ _, err = w.Write(inp)
+ if err != nil {
+ f.Fatalf("failed to write: %s", err)
+ }
+ f.Add(b.Bytes())
+ }
+
+ testdata, err := os.ReadDir("testdata")
+ if err != nil {
+ f.Fatalf("failed to read testdata directory: %s", err)
+ }
+ for _, de := range testdata {
+ if de.IsDir() {
+ continue
+ }
+ b, err := os.ReadFile(filepath.Join("testdata", de.Name()))
+ if err != nil {
+ f.Fatalf("failed to read testdata: %s", err)
+ }
+
+ // decode any base64 encoded test files
+ if strings.HasPrefix(de.Name(), ".base64") {
+ b, err = base64.StdEncoding.DecodeString(string(b))
+ if err != nil {
+ f.Fatalf("failed to decode base64 testdata: %s", err)
+ }
+ }
+
+ f.Add(b)
+ }
+
+ f.Fuzz(func(t *testing.T, b []byte) {
+ for _, multistream := range []bool{true, false} {
+ r, err := NewReader(bytes.NewBuffer(b))
+ if err != nil {
+ continue
+ }
+
+ r.Multistream(multistream)
+
+ decompressed := bytes.NewBuffer(nil)
+ if _, err := io.Copy(decompressed, r); err != nil {
+ continue
+ }
+
+ if err := r.Close(); err != nil {
+ continue
+ }
+
+ for _, level := range []int{NoCompression, BestSpeed, BestCompression, DefaultCompression, HuffmanOnly} {
+ w, err := NewWriterLevel(io.Discard, level)
+ if err != nil {
+ t.Fatalf("failed to construct writer: %s", err)
+ }
+ _, err = w.Write(decompressed.Bytes())
+ if err != nil {
+ t.Fatalf("failed to write: %s", err)
+ }
+ if err := w.Flush(); err != nil {
+ t.Fatalf("failed to flush: %s", err)
+ }
+ if err := w.Close(); err != nil {
+ t.Fatalf("failed to close: %s", err)
+ }
+ }
+ }
+ })
+}
diff --git a/src/compress/gzip/gunzip.go b/src/compress/gzip/gunzip.go
new file mode 100644
index 0000000..ba8de97
--- /dev/null
+++ b/src/compress/gzip/gunzip.go
@@ -0,0 +1,290 @@
+// Copyright 2009 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 gzip implements reading and writing of gzip format compressed files,
+// as specified in RFC 1952.
+package gzip
+
+import (
+ "bufio"
+ "compress/flate"
+ "encoding/binary"
+ "errors"
+ "hash/crc32"
+ "io"
+ "time"
+)
+
+const (
+ gzipID1 = 0x1f
+ gzipID2 = 0x8b
+ gzipDeflate = 8
+ flagText = 1 << 0
+ flagHdrCrc = 1 << 1
+ flagExtra = 1 << 2
+ flagName = 1 << 3
+ flagComment = 1 << 4
+)
+
+var (
+ // ErrChecksum is returned when reading GZIP data that has an invalid checksum.
+ ErrChecksum = errors.New("gzip: invalid checksum")
+ // ErrHeader is returned when reading GZIP data that has an invalid header.
+ ErrHeader = errors.New("gzip: invalid header")
+)
+
+var le = binary.LittleEndian
+
+// noEOF converts io.EOF to io.ErrUnexpectedEOF.
+func noEOF(err error) error {
+ if err == io.EOF {
+ return io.ErrUnexpectedEOF
+ }
+ return err
+}
+
+// The gzip file stores a header giving metadata about the compressed file.
+// That header is exposed as the fields of the Writer and Reader structs.
+//
+// Strings must be UTF-8 encoded and may only contain Unicode code points
+// U+0001 through U+00FF, due to limitations of the GZIP file format.
+type Header struct {
+ Comment string // comment
+ Extra []byte // "extra data"
+ ModTime time.Time // modification time
+ Name string // file name
+ OS byte // operating system type
+}
+
+// A Reader is an io.Reader that can be read to retrieve
+// uncompressed data from a gzip-format compressed file.
+//
+// In general, a gzip file can be a concatenation of gzip files,
+// each with its own header. Reads from the Reader
+// return the concatenation of the uncompressed data of each.
+// Only the first header is recorded in the Reader fields.
+//
+// Gzip files store a length and checksum of the uncompressed data.
+// The Reader will return an ErrChecksum when Read
+// reaches the end of the uncompressed data if it does not
+// have the expected length or checksum. Clients should treat data
+// returned by Read as tentative until they receive the io.EOF
+// marking the end of the data.
+type Reader struct {
+ Header // valid after NewReader or Reader.Reset
+ r flate.Reader
+ decompressor io.ReadCloser
+ digest uint32 // CRC-32, IEEE polynomial (section 8)
+ size uint32 // Uncompressed size (section 2.3.1)
+ buf [512]byte
+ err error
+ multistream bool
+}
+
+// NewReader creates a new Reader reading the given reader.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+//
+// It is the caller's responsibility to call Close on the Reader when done.
+//
+// The Reader.Header fields will be valid in the Reader returned.
+func NewReader(r io.Reader) (*Reader, error) {
+ z := new(Reader)
+ if err := z.Reset(r); err != nil {
+ return nil, err
+ }
+ return z, nil
+}
+
+// Reset discards the Reader z's state and makes it equivalent to the
+// result of its original state from NewReader, but reading from r instead.
+// This permits reusing a Reader rather than allocating a new one.
+func (z *Reader) Reset(r io.Reader) error {
+ *z = Reader{
+ decompressor: z.decompressor,
+ multistream: true,
+ }
+ if rr, ok := r.(flate.Reader); ok {
+ z.r = rr
+ } else {
+ z.r = bufio.NewReader(r)
+ }
+ z.Header, z.err = z.readHeader()
+ return z.err
+}
+
+// Multistream controls whether the reader supports multistream files.
+//
+// If enabled (the default), the Reader expects the input to be a sequence
+// of individually gzipped data streams, each with its own header and
+// trailer, ending at EOF. The effect is that the concatenation of a sequence
+// of gzipped files is treated as equivalent to the gzip of the concatenation
+// of the sequence. This is standard behavior for gzip readers.
+//
+// Calling Multistream(false) disables this behavior; disabling the behavior
+// can be useful when reading file formats that distinguish individual gzip
+// data streams or mix gzip data streams with other data streams.
+// In this mode, when the Reader reaches the end of the data stream,
+// Read returns io.EOF. The underlying reader must implement io.ByteReader
+// in order to be left positioned just after the gzip stream.
+// To start the next stream, call z.Reset(r) followed by z.Multistream(false).
+// If there is no next stream, z.Reset(r) will return io.EOF.
+func (z *Reader) Multistream(ok bool) {
+ z.multistream = ok
+}
+
+// readString reads a NUL-terminated string from z.r.
+// It treats the bytes read as being encoded as ISO 8859-1 (Latin-1) and
+// will output a string encoded using UTF-8.
+// This method always updates z.digest with the data read.
+func (z *Reader) readString() (string, error) {
+ var err error
+ needConv := false
+ for i := 0; ; i++ {
+ if i >= len(z.buf) {
+ return "", ErrHeader
+ }
+ z.buf[i], err = z.r.ReadByte()
+ if err != nil {
+ return "", err
+ }
+ if z.buf[i] > 0x7f {
+ needConv = true
+ }
+ if z.buf[i] == 0 {
+ // Digest covers the NUL terminator.
+ z.digest = crc32.Update(z.digest, crc32.IEEETable, z.buf[:i+1])
+
+ // Strings are ISO 8859-1, Latin-1 (RFC 1952, section 2.3.1).
+ if needConv {
+ s := make([]rune, 0, i)
+ for _, v := range z.buf[:i] {
+ s = append(s, rune(v))
+ }
+ return string(s), nil
+ }
+ return string(z.buf[:i]), nil
+ }
+ }
+}
+
+// readHeader reads the GZIP header according to section 2.3.1.
+// This method does not set z.err.
+func (z *Reader) readHeader() (hdr Header, err error) {
+ if _, err = io.ReadFull(z.r, z.buf[:10]); err != nil {
+ // RFC 1952, section 2.2, says the following:
+ // A gzip file consists of a series of "members" (compressed data sets).
+ //
+ // Other than this, the specification does not clarify whether a
+ // "series" is defined as "one or more" or "zero or more". To err on the
+ // side of caution, Go interprets this to mean "zero or more".
+ // Thus, it is okay to return io.EOF here.
+ return hdr, err
+ }
+ if z.buf[0] != gzipID1 || z.buf[1] != gzipID2 || z.buf[2] != gzipDeflate {
+ return hdr, ErrHeader
+ }
+ flg := z.buf[3]
+ if t := int64(le.Uint32(z.buf[4:8])); t > 0 {
+ // Section 2.3.1, the zero value for MTIME means that the
+ // modified time is not set.
+ hdr.ModTime = time.Unix(t, 0)
+ }
+ // z.buf[8] is XFL and is currently ignored.
+ hdr.OS = z.buf[9]
+ z.digest = crc32.ChecksumIEEE(z.buf[:10])
+
+ if flg&flagExtra != 0 {
+ if _, err = io.ReadFull(z.r, z.buf[:2]); err != nil {
+ return hdr, noEOF(err)
+ }
+ z.digest = crc32.Update(z.digest, crc32.IEEETable, z.buf[:2])
+ data := make([]byte, le.Uint16(z.buf[:2]))
+ if _, err = io.ReadFull(z.r, data); err != nil {
+ return hdr, noEOF(err)
+ }
+ z.digest = crc32.Update(z.digest, crc32.IEEETable, data)
+ hdr.Extra = data
+ }
+
+ var s string
+ if flg&flagName != 0 {
+ if s, err = z.readString(); err != nil {
+ return hdr, noEOF(err)
+ }
+ hdr.Name = s
+ }
+
+ if flg&flagComment != 0 {
+ if s, err = z.readString(); err != nil {
+ return hdr, noEOF(err)
+ }
+ hdr.Comment = s
+ }
+
+ if flg&flagHdrCrc != 0 {
+ if _, err = io.ReadFull(z.r, z.buf[:2]); err != nil {
+ return hdr, noEOF(err)
+ }
+ digest := le.Uint16(z.buf[:2])
+ if digest != uint16(z.digest) {
+ return hdr, ErrHeader
+ }
+ }
+
+ z.digest = 0
+ if z.decompressor == nil {
+ z.decompressor = flate.NewReader(z.r)
+ } else {
+ z.decompressor.(flate.Resetter).Reset(z.r, nil)
+ }
+ return hdr, nil
+}
+
+// Read implements io.Reader, reading uncompressed bytes from its underlying Reader.
+func (z *Reader) Read(p []byte) (n int, err error) {
+ if z.err != nil {
+ return 0, z.err
+ }
+
+ for n == 0 {
+ n, z.err = z.decompressor.Read(p)
+ z.digest = crc32.Update(z.digest, crc32.IEEETable, p[:n])
+ z.size += uint32(n)
+ if z.err != io.EOF {
+ // In the normal case we return here.
+ return n, z.err
+ }
+
+ // Finished file; check checksum and size.
+ if _, err := io.ReadFull(z.r, z.buf[:8]); err != nil {
+ z.err = noEOF(err)
+ return n, z.err
+ }
+ digest := le.Uint32(z.buf[:4])
+ size := le.Uint32(z.buf[4:8])
+ if digest != z.digest || size != z.size {
+ z.err = ErrChecksum
+ return n, z.err
+ }
+ z.digest, z.size = 0, 0
+
+ // File is ok; check if there is another.
+ if !z.multistream {
+ return n, io.EOF
+ }
+ z.err = nil // Remove io.EOF
+
+ if _, z.err = z.readHeader(); z.err != nil {
+ return n, z.err
+ }
+ }
+
+ return n, nil
+}
+
+// Close closes the Reader. It does not close the underlying io.Reader.
+// In order for the GZIP checksum to be verified, the reader must be
+// fully consumed until the io.EOF.
+func (z *Reader) Close() error { return z.decompressor.Close() }
diff --git a/src/compress/gzip/gunzip_test.go b/src/compress/gzip/gunzip_test.go
new file mode 100644
index 0000000..3309ff6
--- /dev/null
+++ b/src/compress/gzip/gunzip_test.go
@@ -0,0 +1,587 @@
+// Copyright 2009 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 gzip
+
+import (
+ "bytes"
+ "compress/flate"
+ "encoding/base64"
+ "io"
+ "os"
+ "strings"
+ "testing"
+ "time"
+)
+
+type gunzipTest struct {
+ name string
+ desc string
+ raw string
+ gzip []byte
+ err error
+}
+
+var gunzipTests = []gunzipTest{
+ { // has 1 empty fixed-huffman block
+ "empty.txt",
+ "empty.txt",
+ "",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xf7, 0x5e, 0x14, 0x4a,
+ 0x00, 0x03, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ nil,
+ },
+ {
+ "",
+ "empty - with no file name",
+ "",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88,
+ 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ },
+ nil,
+ },
+ { // has 1 non-empty fixed huffman block
+ "hello.txt",
+ "hello.txt",
+ "hello world\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+ 0x00, 0x00,
+ },
+ nil,
+ },
+ { // concatenation
+ "hello.txt",
+ "hello.txt x2",
+ "hello world\n" +
+ "hello world\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+ 0x00, 0x00,
+ 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+ 0x00, 0x00,
+ },
+ nil,
+ },
+ { // has a fixed huffman block with some length-distance pairs
+ "shesells.txt",
+ "shesells.txt",
+ "she sells seashells by the seashore\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0x72, 0x66, 0x8b, 0x4a,
+ 0x00, 0x03, 0x73, 0x68, 0x65, 0x73, 0x65, 0x6c,
+ 0x6c, 0x73, 0x2e, 0x74, 0x78, 0x74, 0x00, 0x2b,
+ 0xce, 0x48, 0x55, 0x28, 0x4e, 0xcd, 0xc9, 0x29,
+ 0x06, 0x92, 0x89, 0xc5, 0x19, 0x60, 0x56, 0x52,
+ 0xa5, 0x42, 0x09, 0x58, 0x18, 0x28, 0x90, 0x5f,
+ 0x94, 0xca, 0x05, 0x00, 0x76, 0xb0, 0x3b, 0xeb,
+ 0x24, 0x00, 0x00, 0x00,
+ },
+ nil,
+ },
+ { // has dynamic huffman blocks
+ "gettysburg",
+ "gettysburg",
+ " Four score and seven years ago our fathers brought forth on\n" +
+ "this continent, a new nation, conceived in Liberty, and dedicated\n" +
+ "to the proposition that all men are created equal.\n" +
+ " Now we are engaged in a great Civil War, testing whether that\n" +
+ "nation, or any nation so conceived and so dedicated, can long\n" +
+ "endure.\n" +
+ " We are met on a great battle-field of that war.\n" +
+ " We have come to dedicate a portion of that field, as a final\n" +
+ "resting place for those who here gave their lives that that\n" +
+ "nation might live. It is altogether fitting and proper that\n" +
+ "we should do this.\n" +
+ " But, in a larger sense, we can not dedicate — we can not\n" +
+ "consecrate — we can not hallow — this ground.\n" +
+ " The brave men, living and dead, who struggled here, have\n" +
+ "consecrated it, far above our poor power to add or detract.\n" +
+ "The world will little note, nor long remember what we say here,\n" +
+ "but it can never forget what they did here.\n" +
+ " It is for us the living, rather, to be dedicated here to the\n" +
+ "unfinished work which they who fought here have thus far so\n" +
+ "nobly advanced. It is rather for us to be here dedicated to\n" +
+ "the great task remaining before us — that from these honored\n" +
+ "dead we take increased devotion to that cause for which they\n" +
+ "gave the last full measure of devotion —\n" +
+ " that we here highly resolve that these dead shall not have\n" +
+ "died in vain — that this nation, under God, shall have a new\n" +
+ "birth of freedom — and that government of the people, by the\n" +
+ "people, for the people, shall not perish from this earth.\n" +
+ "\n" +
+ "Abraham Lincoln, November 19, 1863, Gettysburg, Pennsylvania\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xd1, 0x12, 0x2b, 0x4a,
+ 0x00, 0x03, 0x67, 0x65, 0x74, 0x74, 0x79, 0x73,
+ 0x62, 0x75, 0x72, 0x67, 0x00, 0x65, 0x54, 0xcd,
+ 0x6e, 0xd4, 0x30, 0x10, 0xbe, 0xfb, 0x29, 0xe6,
+ 0x01, 0x42, 0xa5, 0x0a, 0x09, 0xc1, 0x11, 0x90,
+ 0x40, 0x48, 0xa8, 0xe2, 0x80, 0xd4, 0xf3, 0x24,
+ 0x9e, 0x24, 0x56, 0xbd, 0x9e, 0xc5, 0x76, 0x76,
+ 0x95, 0x1b, 0x0f, 0xc1, 0x13, 0xf2, 0x24, 0x7c,
+ 0x63, 0x77, 0x9b, 0x4a, 0x5c, 0xaa, 0x6e, 0x6c,
+ 0xcf, 0x7c, 0x7f, 0x33, 0x44, 0x5f, 0x74, 0xcb,
+ 0x54, 0x26, 0xcd, 0x42, 0x9c, 0x3c, 0x15, 0xb9,
+ 0x48, 0xa2, 0x5d, 0x38, 0x17, 0xe2, 0x45, 0xc9,
+ 0x4e, 0x67, 0xae, 0xab, 0xe0, 0xf7, 0x98, 0x75,
+ 0x5b, 0xd6, 0x4a, 0xb3, 0xe6, 0xba, 0x92, 0x26,
+ 0x57, 0xd7, 0x50, 0x68, 0xd2, 0x54, 0x43, 0x92,
+ 0x54, 0x07, 0x62, 0x4a, 0x72, 0xa5, 0xc4, 0x35,
+ 0x68, 0x1a, 0xec, 0x60, 0x92, 0x70, 0x11, 0x4f,
+ 0x21, 0xd1, 0xf7, 0x30, 0x4a, 0xae, 0xfb, 0xd0,
+ 0x9a, 0x78, 0xf1, 0x61, 0xe2, 0x2a, 0xde, 0x55,
+ 0x25, 0xd4, 0xa6, 0x73, 0xd6, 0xb3, 0x96, 0x60,
+ 0xef, 0xf0, 0x9b, 0x2b, 0x71, 0x8c, 0x74, 0x02,
+ 0x10, 0x06, 0xac, 0x29, 0x8b, 0xdd, 0x25, 0xf9,
+ 0xb5, 0x71, 0xbc, 0x73, 0x44, 0x0f, 0x7a, 0xa5,
+ 0xab, 0xb4, 0x33, 0x49, 0x0b, 0x2f, 0xbd, 0x03,
+ 0xd3, 0x62, 0x17, 0xe9, 0x73, 0xb8, 0x84, 0x48,
+ 0x8f, 0x9c, 0x07, 0xaa, 0x52, 0x00, 0x6d, 0xa1,
+ 0xeb, 0x2a, 0xc6, 0xa0, 0x95, 0x76, 0x37, 0x78,
+ 0x9a, 0x81, 0x65, 0x7f, 0x46, 0x4b, 0x45, 0x5f,
+ 0xe1, 0x6d, 0x42, 0xe8, 0x01, 0x13, 0x5c, 0x38,
+ 0x51, 0xd4, 0xb4, 0x38, 0x49, 0x7e, 0xcb, 0x62,
+ 0x28, 0x1e, 0x3b, 0x82, 0x93, 0x54, 0x48, 0xf1,
+ 0xd2, 0x7d, 0xe4, 0x5a, 0xa3, 0xbc, 0x99, 0x83,
+ 0x44, 0x4f, 0x3a, 0x77, 0x36, 0x57, 0xce, 0xcf,
+ 0x2f, 0x56, 0xbe, 0x80, 0x90, 0x9e, 0x84, 0xea,
+ 0x51, 0x1f, 0x8f, 0xcf, 0x90, 0xd4, 0x60, 0xdc,
+ 0x5e, 0xb4, 0xf7, 0x10, 0x0b, 0x26, 0xe0, 0xff,
+ 0xc4, 0xd1, 0xe5, 0x67, 0x2e, 0xe7, 0xc8, 0x93,
+ 0x98, 0x05, 0xb8, 0xa8, 0x45, 0xc0, 0x4d, 0x09,
+ 0xdc, 0x84, 0x16, 0x2b, 0x0d, 0x9a, 0x21, 0x53,
+ 0x04, 0x8b, 0xd2, 0x0b, 0xbd, 0xa2, 0x4c, 0xa7,
+ 0x60, 0xee, 0xd9, 0xe1, 0x1d, 0xd1, 0xb7, 0x4a,
+ 0x30, 0x8f, 0x63, 0xd5, 0xa5, 0x8b, 0x33, 0x87,
+ 0xda, 0x1a, 0x18, 0x79, 0xf3, 0xe3, 0xa6, 0x17,
+ 0x94, 0x2e, 0xab, 0x6e, 0xa0, 0xe3, 0xcd, 0xac,
+ 0x50, 0x8c, 0xca, 0xa7, 0x0d, 0x76, 0x37, 0xd1,
+ 0x23, 0xe7, 0x05, 0x57, 0x8b, 0xa4, 0x22, 0x83,
+ 0xd9, 0x62, 0x52, 0x25, 0xad, 0x07, 0xbb, 0xbf,
+ 0xbf, 0xff, 0xbc, 0xfa, 0xee, 0x20, 0x73, 0x91,
+ 0x29, 0xff, 0x7f, 0x02, 0x71, 0x62, 0x84, 0xb5,
+ 0xf6, 0xb5, 0x25, 0x6b, 0x41, 0xde, 0x92, 0xb7,
+ 0x76, 0x3f, 0x91, 0x91, 0x31, 0x1b, 0x41, 0x84,
+ 0x62, 0x30, 0x0a, 0x37, 0xa4, 0x5e, 0x18, 0x3a,
+ 0x99, 0x08, 0xa5, 0xe6, 0x6d, 0x59, 0x22, 0xec,
+ 0x33, 0x39, 0x86, 0x26, 0xf5, 0xab, 0x66, 0xc8,
+ 0x08, 0x20, 0xcf, 0x0c, 0xd7, 0x47, 0x45, 0x21,
+ 0x0b, 0xf6, 0x59, 0xd5, 0xfe, 0x5c, 0x8d, 0xaa,
+ 0x12, 0x7b, 0x6f, 0xa1, 0xf0, 0x52, 0x33, 0x4f,
+ 0xf5, 0xce, 0x59, 0xd3, 0xab, 0x66, 0x10, 0xbf,
+ 0x06, 0xc4, 0x31, 0x06, 0x73, 0xd6, 0x80, 0xa2,
+ 0x78, 0xc2, 0x45, 0xcb, 0x03, 0x65, 0x39, 0xc9,
+ 0x09, 0xd1, 0x06, 0x04, 0x33, 0x1a, 0x5a, 0xf1,
+ 0xde, 0x01, 0xb8, 0x71, 0x83, 0xc4, 0xb5, 0xb3,
+ 0xc3, 0x54, 0x65, 0x33, 0x0d, 0x5a, 0xf7, 0x9b,
+ 0x90, 0x7c, 0x27, 0x1f, 0x3a, 0x58, 0xa3, 0xd8,
+ 0xfd, 0x30, 0x5f, 0xb7, 0xd2, 0x66, 0xa2, 0x93,
+ 0x1c, 0x28, 0xb7, 0xe9, 0x1b, 0x0c, 0xe1, 0x28,
+ 0x47, 0x26, 0xbb, 0xe9, 0x7d, 0x7e, 0xdc, 0x96,
+ 0x10, 0x92, 0x50, 0x56, 0x7c, 0x06, 0xe2, 0x27,
+ 0xb4, 0x08, 0xd3, 0xda, 0x7b, 0x98, 0x34, 0x73,
+ 0x9f, 0xdb, 0xf6, 0x62, 0xed, 0x31, 0x41, 0x13,
+ 0xd3, 0xa2, 0xa8, 0x4b, 0x3a, 0xc6, 0x1d, 0xe4,
+ 0x2f, 0x8c, 0xf8, 0xfb, 0x97, 0x64, 0xf4, 0xb6,
+ 0x2f, 0x80, 0x5a, 0xf3, 0x56, 0xe0, 0x40, 0x50,
+ 0xd5, 0x19, 0xd0, 0x1e, 0xfc, 0xca, 0xe5, 0xc9,
+ 0xd4, 0x60, 0x00, 0x81, 0x2e, 0xa3, 0xcc, 0xb6,
+ 0x52, 0xf0, 0xb4, 0xdb, 0x69, 0x99, 0xce, 0x7a,
+ 0x32, 0x4c, 0x08, 0xed, 0xaa, 0x10, 0x10, 0xe3,
+ 0x6f, 0xee, 0x99, 0x68, 0x95, 0x9f, 0x04, 0x71,
+ 0xb2, 0x49, 0x2f, 0x62, 0xa6, 0x5e, 0xb4, 0xef,
+ 0x02, 0xed, 0x4f, 0x27, 0xde, 0x4a, 0x0f, 0xfd,
+ 0xc1, 0xcc, 0xdd, 0x02, 0x8f, 0x08, 0x16, 0x54,
+ 0xdf, 0xda, 0xca, 0xe0, 0x82, 0xf1, 0xb4, 0x31,
+ 0x7a, 0xa9, 0x81, 0xfe, 0x90, 0xb7, 0x3e, 0xdb,
+ 0xd3, 0x35, 0xc0, 0x20, 0x80, 0x33, 0x46, 0x4a,
+ 0x63, 0xab, 0xd1, 0x0d, 0x29, 0xd2, 0xe2, 0x84,
+ 0xb8, 0xdb, 0xfa, 0xe9, 0x89, 0x44, 0x86, 0x7c,
+ 0xe8, 0x0b, 0xe6, 0x02, 0x6a, 0x07, 0x9b, 0x96,
+ 0xd0, 0xdb, 0x2e, 0x41, 0x4c, 0xa1, 0xd5, 0x57,
+ 0x45, 0x14, 0xfb, 0xe3, 0xa6, 0x72, 0x5b, 0x87,
+ 0x6e, 0x0c, 0x6d, 0x5b, 0xce, 0xe0, 0x2f, 0xe2,
+ 0x21, 0x81, 0x95, 0xb0, 0xe8, 0xb6, 0x32, 0x0b,
+ 0xb2, 0x98, 0x13, 0x52, 0x5d, 0xfb, 0xec, 0x63,
+ 0x17, 0x8a, 0x9e, 0x23, 0x22, 0x36, 0xee, 0xcd,
+ 0xda, 0xdb, 0xcf, 0x3e, 0xf1, 0xc7, 0xf1, 0x01,
+ 0x12, 0x93, 0x0a, 0xeb, 0x6f, 0xf2, 0x02, 0x15,
+ 0x96, 0x77, 0x5d, 0xef, 0x9c, 0xfb, 0x88, 0x91,
+ 0x59, 0xf9, 0x84, 0xdd, 0x9b, 0x26, 0x8d, 0x80,
+ 0xf9, 0x80, 0x66, 0x2d, 0xac, 0xf7, 0x1f, 0x06,
+ 0xba, 0x7f, 0xff, 0xee, 0xed, 0x40, 0x5f, 0xa5,
+ 0xd6, 0xbd, 0x8c, 0x5b, 0x46, 0xd2, 0x7e, 0x48,
+ 0x4a, 0x65, 0x8f, 0x08, 0x42, 0x60, 0xf7, 0x0f,
+ 0xb9, 0x16, 0x0b, 0x0c, 0x1a, 0x06, 0x00, 0x00,
+ },
+ nil,
+ },
+ { // has 1 non-empty fixed huffman block then garbage
+ "hello.txt",
+ "hello.txt + garbage",
+ "hello world\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+ 0x00, 0x00, 'g', 'a', 'r', 'b', 'a', 'g', 'e', '!', '!', '!',
+ },
+ ErrHeader,
+ },
+ { // has 1 non-empty fixed huffman block not enough header
+ "hello.txt",
+ "hello.txt + garbage",
+ "hello world\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+ 0x00, 0x00, gzipID1,
+ },
+ io.ErrUnexpectedEOF,
+ },
+ { // has 1 non-empty fixed huffman block but corrupt checksum
+ "hello.txt",
+ "hello.txt + corrupt checksum",
+ "hello world\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00,
+ 0x00, 0x00,
+ },
+ ErrChecksum,
+ },
+ { // has 1 non-empty fixed huffman block but corrupt size
+ "hello.txt",
+ "hello.txt + corrupt size",
+ "hello world\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0xff, 0x00,
+ 0x00, 0x00,
+ },
+ ErrChecksum,
+ },
+ {
+ "f1l3n4m3.tXt",
+ "header with all fields used",
+ "",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x1e, 0x70, 0xf0, 0xf9, 0x4a,
+ 0x00, 0xaa, 0x09, 0x00, 0x7a, 0x7a, 0x05, 0x00,
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x31, 0x6c,
+ 0x33, 0x6e, 0x34, 0x6d, 0x33, 0x2e, 0x74, 0x58,
+ 0x74, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
+ 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
+ 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+ 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
+ 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
+ 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
+ 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
+ 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
+ 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+ 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
+ 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
+ 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,
+ 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,
+ 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
+ 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
+ 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
+ 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
+ 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
+ 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
+ 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
+ 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
+ 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
+ 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
+ 0xff, 0x00, 0x92, 0xfd, 0x01, 0x00, 0x00, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ },
+ nil,
+ },
+ {
+ "",
+ "truncated gzip file amid raw-block",
+ "hello",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+ 0x00, 0x0c, 0x00, 0xf3, 0xff, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
+ },
+ io.ErrUnexpectedEOF,
+ },
+ {
+ "",
+ "truncated gzip file amid fixed-block",
+ "He",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+ 0xf2, 0x48, 0xcd,
+ },
+ io.ErrUnexpectedEOF,
+ },
+ {
+ "hello.txt",
+ "gzip header with truncated name",
+ "hello world\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+ 0x00, 0x00,
+ 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0x01,
+ },
+ io.ErrUnexpectedEOF,
+ },
+ {
+ "",
+ "gzip header with truncated comment",
+ "hello world\n",
+ []byte{
+ 0x1f, 0x8b, 0x08, 0x10, 0xc8, 0x58, 0x13, 0x4a,
+ 0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+ 0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+ 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+ 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+ 0x00, 0x00,
+ 0x1f, 0x8b, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0x01,
+ },
+ io.ErrUnexpectedEOF,
+ },
+}
+
+func TestDecompressor(t *testing.T) {
+ // Keep resetting this reader.
+ // It is intended behavior that Reader.Reset can be called on a zero-value
+ // Reader and be the equivalent as if NewReader was used instead.
+ r1 := new(Reader)
+
+ b := new(bytes.Buffer)
+ for _, tt := range gunzipTests {
+ // Test NewReader.
+ in := bytes.NewReader(tt.gzip)
+ r2, err := NewReader(in)
+ if err != nil {
+ t.Errorf("%s: NewReader: %s", tt.desc, err)
+ continue
+ }
+ defer r2.Close()
+ if tt.name != r2.Name {
+ t.Errorf("%s: got name %s", tt.desc, r2.Name)
+ }
+ b.Reset()
+ n, err := io.Copy(b, r2)
+ if err != tt.err {
+ t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
+ }
+ s := b.String()
+ if s != tt.raw {
+ t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
+ }
+
+ // Test Reader.Reset.
+ in = bytes.NewReader(tt.gzip)
+ err = r1.Reset(in)
+ if err != nil {
+ t.Errorf("%s: Reset: %s", tt.desc, err)
+ continue
+ }
+ if tt.name != r1.Name {
+ t.Errorf("%s: got name %s", tt.desc, r1.Name)
+ }
+ b.Reset()
+ n, err = io.Copy(b, r1)
+ if err != tt.err {
+ t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
+ }
+ s = b.String()
+ if s != tt.raw {
+ t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
+ }
+ }
+}
+
+func TestIssue6550(t *testing.T) {
+ // Apple’s notarization service will recursively attempt to decompress
+ // files in order to find binaries to notarize. Since the service is
+ // unable to decompress this file, it may reject the entire toolchain. Use a
+ // base64-encoded version to avoid this.
+ // See golang.org/issue/34986
+ f, err := os.Open("testdata/issue6550.gz.base64")
+ if err != nil {
+ t.Fatal(err)
+ }
+ gzip, err := NewReader(base64.NewDecoder(base64.StdEncoding, f))
+ if err != nil {
+ t.Fatalf("NewReader(testdata/issue6550.gz): %v", err)
+ }
+ defer gzip.Close()
+ done := make(chan bool, 1)
+ go func() {
+ _, err := io.Copy(io.Discard, gzip)
+ if err == nil {
+ t.Errorf("Copy succeeded")
+ } else {
+ t.Logf("Copy failed (correctly): %v", err)
+ }
+ done <- true
+ }()
+ select {
+ case <-time.After(1 * time.Second):
+ t.Errorf("Copy hung")
+ case <-done:
+ // ok
+ }
+}
+
+func TestMultistreamFalse(t *testing.T) {
+ // Find concatenation test.
+ var tt gunzipTest
+ for _, tt = range gunzipTests {
+ if strings.HasSuffix(tt.desc, " x2") {
+ goto Found
+ }
+ }
+ t.Fatal("cannot find hello.txt x2 in gunzip tests")
+
+Found:
+ br := bytes.NewReader(tt.gzip)
+ var r Reader
+ if err := r.Reset(br); err != nil {
+ t.Fatalf("first reset: %v", err)
+ }
+
+ // Expect two streams with "hello world\n", then real EOF.
+ const hello = "hello world\n"
+
+ r.Multistream(false)
+ data, err := io.ReadAll(&r)
+ if string(data) != hello || err != nil {
+ t.Fatalf("first stream = %q, %v, want %q, %v", string(data), err, hello, nil)
+ }
+
+ if err := r.Reset(br); err != nil {
+ t.Fatalf("second reset: %v", err)
+ }
+ r.Multistream(false)
+ data, err = io.ReadAll(&r)
+ if string(data) != hello || err != nil {
+ t.Fatalf("second stream = %q, %v, want %q, %v", string(data), err, hello, nil)
+ }
+
+ if err := r.Reset(br); err != io.EOF {
+ t.Fatalf("third reset: err=%v, want io.EOF", err)
+ }
+}
+
+func TestNilStream(t *testing.T) {
+ // Go liberally interprets RFC 1952 section 2.2 to mean that a gzip file
+ // consist of zero or more members. Thus, we test that a nil stream is okay.
+ _, err := NewReader(bytes.NewReader(nil))
+ if err != io.EOF {
+ t.Fatalf("NewReader(nil) on empty stream: got %v, want io.EOF", err)
+ }
+}
+
+func TestTruncatedStreams(t *testing.T) {
+ cases := []struct {
+ name string
+ data []byte
+ }{
+ {
+ name: "original",
+ data: []byte("\x1f\x8b\b\x04\x00\tn\x88\x00\xff\a\x00foo bar\xcbH\xcd\xc9\xc9\xd7Q(\xcf/\xcaI\x01\x04:r\xab\xff\f\x00\x00\x00"),
+ },
+ {
+ name: "truncated name",
+ data: []byte{
+ 0x1f, 0x8b, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01,
+ },
+ },
+ {
+ name: "truncated comment",
+ data: []byte{
+ 0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01,
+ },
+ },
+ }
+
+ // Intentionally iterate starting with at least one byte in the stream.
+ for _, tc := range cases {
+ for i := 1; i < len(tc.data); i++ {
+ r, err := NewReader(strings.NewReader(string(tc.data[:i])))
+ if err != nil {
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("NewReader(%s-%d) on truncated stream: got %v, want %v", tc.name, i, err, io.ErrUnexpectedEOF)
+ }
+ continue
+ }
+ _, err = io.Copy(io.Discard, r)
+ if ferr, ok := err.(*flate.ReadError); ok {
+ err = ferr.Err
+ }
+ if err != io.ErrUnexpectedEOF {
+ t.Errorf("io.Copy(%s-%d) on truncated stream: got %v, want %v", tc.name, i, err, io.ErrUnexpectedEOF)
+ }
+ }
+ }
+}
+
+func TestCVE202230631(t *testing.T) {
+ var empty = []byte{0x1f, 0x8b, 0x08, 0x00, 0xa7, 0x8f, 0x43, 0x62, 0x00,
+ 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+ r := bytes.NewReader(bytes.Repeat(empty, 4e6))
+ z, err := NewReader(r)
+ if err != nil {
+ t.Fatalf("NewReader: got %v, want nil", err)
+ }
+ // Prior to CVE-2022-30631 fix, this would cause an unrecoverable panic due
+ // to stack exhaustion.
+ _, err = z.Read(make([]byte, 10))
+ if err != io.EOF {
+ t.Errorf("Reader.Read: got %v, want %v", err, io.EOF)
+ }
+}
diff --git a/src/compress/gzip/gzip.go b/src/compress/gzip/gzip.go
new file mode 100644
index 0000000..eaeb185
--- /dev/null
+++ b/src/compress/gzip/gzip.go
@@ -0,0 +1,250 @@
+// 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 gzip
+
+import (
+ "compress/flate"
+ "errors"
+ "fmt"
+ "hash/crc32"
+ "io"
+ "time"
+)
+
+// These constants are copied from the flate package, so that code that imports
+// "compress/gzip" does not also have to import "compress/flate".
+const (
+ NoCompression = flate.NoCompression
+ BestSpeed = flate.BestSpeed
+ BestCompression = flate.BestCompression
+ DefaultCompression = flate.DefaultCompression
+ HuffmanOnly = flate.HuffmanOnly
+)
+
+// A Writer is an io.WriteCloser.
+// Writes to a Writer are compressed and written to w.
+type Writer struct {
+ Header // written at first call to Write, Flush, or Close
+ w io.Writer
+ level int
+ wroteHeader bool
+ compressor *flate.Writer
+ digest uint32 // CRC-32, IEEE polynomial (section 8)
+ size uint32 // Uncompressed size (section 2.3.1)
+ closed bool
+ buf [10]byte
+ err error
+}
+
+// NewWriter returns a new Writer.
+// Writes to the returned writer are compressed and written to w.
+//
+// It is the caller's responsibility to call Close on the Writer when done.
+// Writes may be buffered and not flushed until Close.
+//
+// Callers that wish to set the fields in Writer.Header must do so before
+// the first call to Write, Flush, or Close.
+func NewWriter(w io.Writer) *Writer {
+ z, _ := NewWriterLevel(w, DefaultCompression)
+ return z
+}
+
+// NewWriterLevel is like NewWriter but specifies the compression level instead
+// of assuming DefaultCompression.
+//
+// The compression level can be DefaultCompression, NoCompression, HuffmanOnly
+// or any integer value between BestSpeed and BestCompression inclusive.
+// The error returned will be nil if the level is valid.
+func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
+ if level < HuffmanOnly || level > BestCompression {
+ return nil, fmt.Errorf("gzip: invalid compression level: %d", level)
+ }
+ z := new(Writer)
+ z.init(w, level)
+ return z, nil
+}
+
+func (z *Writer) init(w io.Writer, level int) {
+ compressor := z.compressor
+ if compressor != nil {
+ compressor.Reset(w)
+ }
+ *z = Writer{
+ Header: Header{
+ OS: 255, // unknown
+ },
+ w: w,
+ level: level,
+ compressor: compressor,
+ }
+}
+
+// Reset discards the Writer z's state and makes it equivalent to the
+// result of its original state from NewWriter or NewWriterLevel, but
+// writing to w instead. This permits reusing a Writer rather than
+// allocating a new one.
+func (z *Writer) Reset(w io.Writer) {
+ z.init(w, z.level)
+}
+
+// writeBytes writes a length-prefixed byte slice to z.w.
+func (z *Writer) writeBytes(b []byte) error {
+ if len(b) > 0xffff {
+ return errors.New("gzip.Write: Extra data is too large")
+ }
+ le.PutUint16(z.buf[:2], uint16(len(b)))
+ _, err := z.w.Write(z.buf[:2])
+ if err != nil {
+ return err
+ }
+ _, err = z.w.Write(b)
+ return err
+}
+
+// writeString writes a UTF-8 string s in GZIP's format to z.w.
+// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).
+func (z *Writer) writeString(s string) (err error) {
+ // GZIP stores Latin-1 strings; error if non-Latin-1; convert if non-ASCII.
+ needconv := false
+ for _, v := range s {
+ if v == 0 || v > 0xff {
+ return errors.New("gzip.Write: non-Latin-1 header string")
+ }
+ if v > 0x7f {
+ needconv = true
+ }
+ }
+ if needconv {
+ b := make([]byte, 0, len(s))
+ for _, v := range s {
+ b = append(b, byte(v))
+ }
+ _, err = z.w.Write(b)
+ } else {
+ _, err = io.WriteString(z.w, s)
+ }
+ if err != nil {
+ return err
+ }
+ // GZIP strings are NUL-terminated.
+ z.buf[0] = 0
+ _, err = z.w.Write(z.buf[:1])
+ return err
+}
+
+// Write writes a compressed form of p to the underlying io.Writer. The
+// compressed bytes are not necessarily flushed until the Writer is closed.
+func (z *Writer) Write(p []byte) (int, error) {
+ if z.err != nil {
+ return 0, z.err
+ }
+ var n int
+ // Write the GZIP header lazily.
+ if !z.wroteHeader {
+ z.wroteHeader = true
+ z.buf = [10]byte{0: gzipID1, 1: gzipID2, 2: gzipDeflate}
+ if z.Extra != nil {
+ z.buf[3] |= 0x04
+ }
+ if z.Name != "" {
+ z.buf[3] |= 0x08
+ }
+ if z.Comment != "" {
+ z.buf[3] |= 0x10
+ }
+ if z.ModTime.After(time.Unix(0, 0)) {
+ // Section 2.3.1, the zero value for MTIME means that the
+ // modified time is not set.
+ le.PutUint32(z.buf[4:8], uint32(z.ModTime.Unix()))
+ }
+ if z.level == BestCompression {
+ z.buf[8] = 2
+ } else if z.level == BestSpeed {
+ z.buf[8] = 4
+ }
+ z.buf[9] = z.OS
+ _, z.err = z.w.Write(z.buf[:10])
+ if z.err != nil {
+ return 0, z.err
+ }
+ if z.Extra != nil {
+ z.err = z.writeBytes(z.Extra)
+ if z.err != nil {
+ return 0, z.err
+ }
+ }
+ if z.Name != "" {
+ z.err = z.writeString(z.Name)
+ if z.err != nil {
+ return 0, z.err
+ }
+ }
+ if z.Comment != "" {
+ z.err = z.writeString(z.Comment)
+ if z.err != nil {
+ return 0, z.err
+ }
+ }
+ if z.compressor == nil {
+ z.compressor, _ = flate.NewWriter(z.w, z.level)
+ }
+ }
+ z.size += uint32(len(p))
+ z.digest = crc32.Update(z.digest, crc32.IEEETable, p)
+ n, z.err = z.compressor.Write(p)
+ return n, z.err
+}
+
+// Flush flushes any pending compressed data to the underlying writer.
+//
+// It is useful mainly in compressed network protocols, to ensure that
+// a remote reader has enough data to reconstruct a packet. Flush does
+// not return until the data has been written. If the underlying
+// writer returns an error, Flush returns that error.
+//
+// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.
+func (z *Writer) Flush() error {
+ if z.err != nil {
+ return z.err
+ }
+ if z.closed {
+ return nil
+ }
+ if !z.wroteHeader {
+ z.Write(nil)
+ if z.err != nil {
+ return z.err
+ }
+ }
+ z.err = z.compressor.Flush()
+ return z.err
+}
+
+// Close closes the Writer by flushing any unwritten data to the underlying
+// io.Writer and writing the GZIP footer.
+// It does not close the underlying io.Writer.
+func (z *Writer) Close() error {
+ if z.err != nil {
+ return z.err
+ }
+ if z.closed {
+ return nil
+ }
+ z.closed = true
+ if !z.wroteHeader {
+ z.Write(nil)
+ if z.err != nil {
+ return z.err
+ }
+ }
+ z.err = z.compressor.Close()
+ if z.err != nil {
+ return z.err
+ }
+ le.PutUint32(z.buf[:4], z.digest)
+ le.PutUint32(z.buf[4:8], z.size)
+ _, z.err = z.w.Write(z.buf[:8])
+ return z.err
+}
diff --git a/src/compress/gzip/gzip_test.go b/src/compress/gzip/gzip_test.go
new file mode 100644
index 0000000..12c8e18
--- /dev/null
+++ b/src/compress/gzip/gzip_test.go
@@ -0,0 +1,275 @@
+// 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 gzip
+
+import (
+ "bufio"
+ "bytes"
+ "io"
+ "reflect"
+ "testing"
+ "time"
+)
+
+// TestEmpty tests that an empty payload still forms a valid GZIP stream.
+func TestEmpty(t *testing.T) {
+ buf := new(bytes.Buffer)
+
+ if err := NewWriter(buf).Close(); err != nil {
+ t.Fatalf("Writer.Close: %v", err)
+ }
+
+ r, err := NewReader(buf)
+ if err != nil {
+ t.Fatalf("NewReader: %v", err)
+ }
+ if want := (Header{OS: 255}); !reflect.DeepEqual(r.Header, want) {
+ t.Errorf("Header mismatch:\ngot %#v\nwant %#v", r.Header, want)
+ }
+ b, err := io.ReadAll(r)
+ if err != nil {
+ t.Fatalf("ReadAll: %v", err)
+ }
+ if len(b) != 0 {
+ t.Fatalf("got %d bytes, want 0", len(b))
+ }
+ if err := r.Close(); err != nil {
+ t.Fatalf("Reader.Close: %v", err)
+ }
+}
+
+// TestRoundTrip tests that gzipping and then gunzipping is the identity
+// function.
+func TestRoundTrip(t *testing.T) {
+ buf := new(bytes.Buffer)
+
+ w := NewWriter(buf)
+ w.Comment = "comment"
+ w.Extra = []byte("extra")
+ w.ModTime = time.Unix(1e8, 0)
+ w.Name = "name"
+ if _, err := w.Write([]byte("payload")); err != nil {
+ t.Fatalf("Write: %v", err)
+ }
+ if err := w.Close(); err != nil {
+ t.Fatalf("Writer.Close: %v", err)
+ }
+
+ r, err := NewReader(buf)
+ if err != nil {
+ t.Fatalf("NewReader: %v", err)
+ }
+ b, err := io.ReadAll(r)
+ if err != nil {
+ t.Fatalf("ReadAll: %v", err)
+ }
+ if string(b) != "payload" {
+ t.Fatalf("payload is %q, want %q", string(b), "payload")
+ }
+ if r.Comment != "comment" {
+ t.Fatalf("comment is %q, want %q", r.Comment, "comment")
+ }
+ if string(r.Extra) != "extra" {
+ t.Fatalf("extra is %q, want %q", r.Extra, "extra")
+ }
+ if r.ModTime.Unix() != 1e8 {
+ t.Fatalf("mtime is %d, want %d", r.ModTime.Unix(), uint32(1e8))
+ }
+ if r.Name != "name" {
+ t.Fatalf("name is %q, want %q", r.Name, "name")
+ }
+ if err := r.Close(); err != nil {
+ t.Fatalf("Reader.Close: %v", err)
+ }
+}
+
+// TestLatin1 tests the internal functions for converting to and from Latin-1.
+func TestLatin1(t *testing.T) {
+ latin1 := []byte{0xc4, 'u', 0xdf, 'e', 'r', 'u', 'n', 'g', 0}
+ utf8 := "Äußerung"
+ z := Reader{r: bufio.NewReader(bytes.NewReader(latin1))}
+ s, err := z.readString()
+ if err != nil {
+ t.Fatalf("readString: %v", err)
+ }
+ if s != utf8 {
+ t.Fatalf("read latin-1: got %q, want %q", s, utf8)
+ }
+
+ buf := bytes.NewBuffer(make([]byte, 0, len(latin1)))
+ c := Writer{w: buf}
+ if err = c.writeString(utf8); err != nil {
+ t.Fatalf("writeString: %v", err)
+ }
+ s = buf.String()
+ if s != string(latin1) {
+ t.Fatalf("write utf-8: got %q, want %q", s, string(latin1))
+ }
+}
+
+// TestLatin1RoundTrip tests that metadata that is representable in Latin-1
+// survives a round trip.
+func TestLatin1RoundTrip(t *testing.T) {
+ testCases := []struct {
+ name string
+ ok bool
+ }{
+ {"", true},
+ {"ASCII is OK", true},
+ {"unless it contains a NUL\x00", false},
+ {"no matter where \x00 occurs", false},
+ {"\x00\x00\x00", false},
+ {"Látin-1 also passes (U+00E1)", true},
+ {"but LÄ€tin Extended-A (U+0100) does not", false},
+ {"neither does 日本語", false},
+ {"invalid UTF-8 also \xffails", false},
+ {"\x00 as does Látin-1 with NUL", false},
+ }
+ for _, tc := range testCases {
+ buf := new(bytes.Buffer)
+
+ w := NewWriter(buf)
+ w.Name = tc.name
+ err := w.Close()
+ if (err == nil) != tc.ok {
+ t.Errorf("Writer.Close: name = %q, err = %v", tc.name, err)
+ continue
+ }
+ if !tc.ok {
+ continue
+ }
+
+ r, err := NewReader(buf)
+ if err != nil {
+ t.Errorf("NewReader: %v", err)
+ continue
+ }
+ _, err = io.ReadAll(r)
+ if err != nil {
+ t.Errorf("ReadAll: %v", err)
+ continue
+ }
+ if r.Name != tc.name {
+ t.Errorf("name is %q, want %q", r.Name, tc.name)
+ continue
+ }
+ if err := r.Close(); err != nil {
+ t.Errorf("Reader.Close: %v", err)
+ continue
+ }
+ }
+}
+
+func TestWriterFlush(t *testing.T) {
+ buf := new(bytes.Buffer)
+
+ w := NewWriter(buf)
+ w.Comment = "comment"
+ w.Extra = []byte("extra")
+ w.ModTime = time.Unix(1e8, 0)
+ w.Name = "name"
+
+ n0 := buf.Len()
+ if n0 != 0 {
+ t.Fatalf("buffer size = %d before writes; want 0", n0)
+ }
+
+ if err := w.Flush(); err != nil {
+ t.Fatal(err)
+ }
+
+ n1 := buf.Len()
+ if n1 == 0 {
+ t.Fatal("no data after first flush")
+ }
+
+ w.Write([]byte("x"))
+
+ n2 := buf.Len()
+ if n1 != n2 {
+ t.Fatalf("after writing a single byte, size changed from %d to %d; want no change", n1, n2)
+ }
+
+ if err := w.Flush(); err != nil {
+ t.Fatal(err)
+ }
+
+ n3 := buf.Len()
+ if n2 == n3 {
+ t.Fatal("Flush didn't flush any data")
+ }
+}
+
+// Multiple gzip files concatenated form a valid gzip file.
+func TestConcat(t *testing.T) {
+ var buf bytes.Buffer
+ w := NewWriter(&buf)
+ w.Write([]byte("hello "))
+ w.Close()
+ w = NewWriter(&buf)
+ w.Write([]byte("world\n"))
+ w.Close()
+
+ r, err := NewReader(&buf)
+ if err != nil {
+ t.Fatal(err)
+ }
+ data, err := io.ReadAll(r)
+ if string(data) != "hello world\n" || err != nil {
+ t.Fatalf("ReadAll = %q, %v, want %q, nil", data, err, "hello world")
+ }
+}
+
+func TestWriterReset(t *testing.T) {
+ buf := new(bytes.Buffer)
+ buf2 := new(bytes.Buffer)
+ z := NewWriter(buf)
+ msg := []byte("hello world")
+ z.Write(msg)
+ z.Close()
+ z.Reset(buf2)
+ z.Write(msg)
+ z.Close()
+ if buf.String() != buf2.String() {
+ t.Errorf("buf2 %q != original buf of %q", buf2.String(), buf.String())
+ }
+}
+
+type limitedWriter struct {
+ N int
+}
+
+func (l *limitedWriter) Write(p []byte) (n int, err error) {
+ if n := l.N; n < len(p) {
+ l.N = 0
+ return n, io.ErrShortWrite
+ }
+ l.N -= len(p)
+ return len(p), nil
+}
+
+// Write should never return more bytes than the input slice.
+func TestLimitedWrite(t *testing.T) {
+ msg := []byte("a")
+
+ for lim := 2; lim < 20; lim++ {
+ z := NewWriter(&limitedWriter{lim})
+ if n, _ := z.Write(msg); n > len(msg) {
+ t.Errorf("Write() = %d, want %d or less", n, len(msg))
+ }
+
+ z.Reset(&limitedWriter{lim})
+ z.Header = Header{
+ Comment: "comment",
+ Extra: []byte("extra"),
+ ModTime: time.Now(),
+ Name: "name",
+ OS: 1,
+ }
+ if n, _ := z.Write(msg); n > len(msg) {
+ t.Errorf("Write() = %d, want %d or less", n, len(msg))
+ }
+ }
+}
diff --git a/src/compress/gzip/issue14937_test.go b/src/compress/gzip/issue14937_test.go
new file mode 100644
index 0000000..faee9bd
--- /dev/null
+++ b/src/compress/gzip/issue14937_test.go
@@ -0,0 +1,77 @@
+// Copyright 2016 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 gzip
+
+import (
+ "internal/testenv"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+)
+
+// TestGZIPFilesHaveZeroMTimes checks that every .gz file in the tree
+// has a zero MTIME. This is a requirement for the Debian maintainers
+// to be able to have deterministic packages.
+//
+// See https://golang.org/issue/14937.
+func TestGZIPFilesHaveZeroMTimes(t *testing.T) {
+ // To avoid spurious false positives due to untracked GZIP files that
+ // may be in the user's GOROOT (Issue 18604), we only run this test on
+ // the builders, which should have a clean checkout of the tree.
+ if testenv.Builder() == "" {
+ t.Skip("skipping test on non-builder")
+ }
+ if !testenv.HasSrc() {
+ t.Skip("skipping; no GOROOT available")
+ }
+
+ goroot, err := filepath.EvalSymlinks(runtime.GOROOT())
+ if err != nil {
+ t.Fatal("error evaluating GOROOT: ", err)
+ }
+ var files []string
+ err = filepath.WalkDir(goroot, func(path string, info fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if !info.IsDir() && strings.HasSuffix(path, ".gz") {
+ files = append(files, path)
+ }
+ return nil
+ })
+ if err != nil {
+ if os.IsNotExist(err) {
+ t.Skipf("skipping: GOROOT directory not found: %s", runtime.GOROOT())
+ }
+ t.Fatal("error collecting list of .gz files in GOROOT: ", err)
+ }
+ if len(files) == 0 {
+ t.Fatal("expected to find some .gz files under GOROOT")
+ }
+ for _, path := range files {
+ checkZeroMTime(t, path)
+ }
+}
+
+func checkZeroMTime(t *testing.T, path string) {
+ f, err := os.Open(path)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ defer f.Close()
+ gz, err := NewReader(f)
+ if err != nil {
+ t.Errorf("cannot read gzip file %s: %s", path, err)
+ return
+ }
+ defer gz.Close()
+ if !gz.ModTime.IsZero() {
+ t.Errorf("gzip file %s has non-zero mtime (%s)", path, gz.ModTime)
+ }
+}
diff --git a/src/compress/gzip/testdata/issue6550.gz.base64 b/src/compress/gzip/testdata/issue6550.gz.base64
new file mode 100644
index 0000000..f2509ff
--- /dev/null
+++ b/src/compress/gzip/testdata/issue6550.gz.base64
@@ -0,0 +1 @@
+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
diff --git a/src/compress/lzw/reader.go b/src/compress/lzw/reader.go
new file mode 100644
index 0000000..18df970
--- /dev/null
+++ b/src/compress/lzw/reader.go
@@ -0,0 +1,290 @@
+// Copyright 2011 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 lzw implements the Lempel-Ziv-Welch compressed data format,
+// described in T. A. Welch, “A Technique for High-Performance Data
+// Compressionâ€, Computer, 17(6) (June 1984), pp 8-19.
+//
+// In particular, it implements LZW as used by the GIF and PDF file
+// formats, which means variable-width codes up to 12 bits and the first
+// two non-literal codes are a clear code and an EOF code.
+//
+// The TIFF file format uses a similar but incompatible version of the LZW
+// algorithm. See the golang.org/x/image/tiff/lzw package for an
+// implementation.
+package lzw
+
+// TODO(nigeltao): check that PDF uses LZW in the same way as GIF,
+// modulo LSB/MSB packing order.
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+)
+
+// Order specifies the bit ordering in an LZW data stream.
+type Order int
+
+const (
+ // LSB means Least Significant Bits first, as used in the GIF file format.
+ LSB Order = iota
+ // MSB means Most Significant Bits first, as used in the TIFF and PDF
+ // file formats.
+ MSB
+)
+
+const (
+ maxWidth = 12
+ decoderInvalidCode = 0xffff
+ flushBuffer = 1 << maxWidth
+)
+
+// Reader is an io.Reader which can be used to read compressed data in the
+// LZW format.
+type Reader struct {
+ r io.ByteReader
+ bits uint32
+ nBits uint
+ width uint
+ read func(*Reader) (uint16, error) // readLSB or readMSB
+ litWidth int // width in bits of literal codes
+ err error
+
+ // The first 1<<litWidth codes are literal codes.
+ // The next two codes mean clear and EOF.
+ // Other valid codes are in the range [lo, hi] where lo := clear + 2,
+ // with the upper bound incrementing on each code seen.
+ //
+ // overflow is the code at which hi overflows the code width. It always
+ // equals 1 << width.
+ //
+ // last is the most recently seen code, or decoderInvalidCode.
+ //
+ // An invariant is that hi < overflow.
+ clear, eof, hi, overflow, last uint16
+
+ // Each code c in [lo, hi] expands to two or more bytes. For c != hi:
+ // suffix[c] is the last of these bytes.
+ // prefix[c] is the code for all but the last byte.
+ // This code can either be a literal code or another code in [lo, c).
+ // The c == hi case is a special case.
+ suffix [1 << maxWidth]uint8
+ prefix [1 << maxWidth]uint16
+
+ // output is the temporary output buffer.
+ // Literal codes are accumulated from the start of the buffer.
+ // Non-literal codes decode to a sequence of suffixes that are first
+ // written right-to-left from the end of the buffer before being copied
+ // to the start of the buffer.
+ // It is flushed when it contains >= 1<<maxWidth bytes,
+ // so that there is always room to decode an entire code.
+ output [2 * 1 << maxWidth]byte
+ o int // write index into output
+ toRead []byte // bytes to return from Read
+}
+
+// readLSB returns the next code for "Least Significant Bits first" data.
+func (r *Reader) readLSB() (uint16, error) {
+ for r.nBits < r.width {
+ x, err := r.r.ReadByte()
+ if err != nil {
+ return 0, err
+ }
+ r.bits |= uint32(x) << r.nBits
+ r.nBits += 8
+ }
+ code := uint16(r.bits & (1<<r.width - 1))
+ r.bits >>= r.width
+ r.nBits -= r.width
+ return code, nil
+}
+
+// readMSB returns the next code for "Most Significant Bits first" data.
+func (r *Reader) readMSB() (uint16, error) {
+ for r.nBits < r.width {
+ x, err := r.r.ReadByte()
+ if err != nil {
+ return 0, err
+ }
+ r.bits |= uint32(x) << (24 - r.nBits)
+ r.nBits += 8
+ }
+ code := uint16(r.bits >> (32 - r.width))
+ r.bits <<= r.width
+ r.nBits -= r.width
+ return code, nil
+}
+
+// Read implements io.Reader, reading uncompressed bytes from its underlying Reader.
+func (r *Reader) Read(b []byte) (int, error) {
+ for {
+ if len(r.toRead) > 0 {
+ n := copy(b, r.toRead)
+ r.toRead = r.toRead[n:]
+ return n, nil
+ }
+ if r.err != nil {
+ return 0, r.err
+ }
+ r.decode()
+ }
+}
+
+// decode decompresses bytes from r and leaves them in d.toRead.
+// read specifies how to decode bytes into codes.
+// litWidth is the width in bits of literal codes.
+func (r *Reader) decode() {
+ // Loop over the code stream, converting codes into decompressed bytes.
+loop:
+ for {
+ code, err := r.read(r)
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ r.err = err
+ break
+ }
+ switch {
+ case code < r.clear:
+ // We have a literal code.
+ r.output[r.o] = uint8(code)
+ r.o++
+ if r.last != decoderInvalidCode {
+ // Save what the hi code expands to.
+ r.suffix[r.hi] = uint8(code)
+ r.prefix[r.hi] = r.last
+ }
+ case code == r.clear:
+ r.width = 1 + uint(r.litWidth)
+ r.hi = r.eof
+ r.overflow = 1 << r.width
+ r.last = decoderInvalidCode
+ continue
+ case code == r.eof:
+ r.err = io.EOF
+ break loop
+ case code <= r.hi:
+ c, i := code, len(r.output)-1
+ if code == r.hi && r.last != decoderInvalidCode {
+ // code == hi is a special case which expands to the last expansion
+ // followed by the head of the last expansion. To find the head, we walk
+ // the prefix chain until we find a literal code.
+ c = r.last
+ for c >= r.clear {
+ c = r.prefix[c]
+ }
+ r.output[i] = uint8(c)
+ i--
+ c = r.last
+ }
+ // Copy the suffix chain into output and then write that to w.
+ for c >= r.clear {
+ r.output[i] = r.suffix[c]
+ i--
+ c = r.prefix[c]
+ }
+ r.output[i] = uint8(c)
+ r.o += copy(r.output[r.o:], r.output[i:])
+ if r.last != decoderInvalidCode {
+ // Save what the hi code expands to.
+ r.suffix[r.hi] = uint8(c)
+ r.prefix[r.hi] = r.last
+ }
+ default:
+ r.err = errors.New("lzw: invalid code")
+ break loop
+ }
+ r.last, r.hi = code, r.hi+1
+ if r.hi >= r.overflow {
+ if r.hi > r.overflow {
+ panic("unreachable")
+ }
+ if r.width == maxWidth {
+ r.last = decoderInvalidCode
+ // Undo the d.hi++ a few lines above, so that (1) we maintain
+ // the invariant that d.hi < d.overflow, and (2) d.hi does not
+ // eventually overflow a uint16.
+ r.hi--
+ } else {
+ r.width++
+ r.overflow = 1 << r.width
+ }
+ }
+ if r.o >= flushBuffer {
+ break
+ }
+ }
+ // Flush pending output.
+ r.toRead = r.output[:r.o]
+ r.o = 0
+}
+
+var errClosed = errors.New("lzw: reader/writer is closed")
+
+// Close closes the Reader and returns an error for any future read operation.
+// It does not close the underlying io.Reader.
+func (r *Reader) Close() error {
+ r.err = errClosed // in case any Reads come along
+ return nil
+}
+
+// Reset clears the Reader's state and allows it to be reused again
+// as a new Reader.
+func (r *Reader) Reset(src io.Reader, order Order, litWidth int) {
+ *r = Reader{}
+ r.init(src, order, litWidth)
+}
+
+// NewReader creates a new io.ReadCloser.
+// Reads from the returned io.ReadCloser read and decompress data from r.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+// It is the caller's responsibility to call Close on the ReadCloser when
+// finished reading.
+// The number of bits to use for literal codes, litWidth, must be in the
+// range [2,8] and is typically 8. It must equal the litWidth
+// used during compression.
+//
+// It is guaranteed that the underlying type of the returned io.ReadCloser
+// is a *Reader.
+func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
+ return newReader(r, order, litWidth)
+}
+
+func newReader(src io.Reader, order Order, litWidth int) *Reader {
+ r := new(Reader)
+ r.init(src, order, litWidth)
+ return r
+}
+
+func (r *Reader) init(src io.Reader, order Order, litWidth int) {
+ switch order {
+ case LSB:
+ r.read = (*Reader).readLSB
+ case MSB:
+ r.read = (*Reader).readMSB
+ default:
+ r.err = errors.New("lzw: unknown order")
+ return
+ }
+ if litWidth < 2 || 8 < litWidth {
+ r.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
+ return
+ }
+
+ br, ok := src.(io.ByteReader)
+ if !ok && src != nil {
+ br = bufio.NewReader(src)
+ }
+ r.r = br
+ r.litWidth = litWidth
+ r.width = 1 + uint(litWidth)
+ r.clear = uint16(1) << uint(litWidth)
+ r.eof, r.hi = r.clear+1, r.clear+1
+ r.overflow = uint16(1) << r.width
+ r.last = decoderInvalidCode
+}
diff --git a/src/compress/lzw/reader_test.go b/src/compress/lzw/reader_test.go
new file mode 100644
index 0000000..9a2a477
--- /dev/null
+++ b/src/compress/lzw/reader_test.go
@@ -0,0 +1,315 @@
+// Copyright 2011 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 lzw
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "math"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+ "testing"
+)
+
+type lzwTest struct {
+ desc string
+ raw string
+ compressed string
+ err error
+}
+
+var lzwTests = []lzwTest{
+ {
+ "empty;LSB;8",
+ "",
+ "\x01\x01",
+ nil,
+ },
+ {
+ "empty;MSB;8",
+ "",
+ "\x80\x80",
+ nil,
+ },
+ {
+ "tobe;LSB;7",
+ "TOBEORNOTTOBEORTOBEORNOT",
+ "\x54\x4f\x42\x45\x4f\x52\x4e\x4f\x54\x82\x84\x86\x8b\x85\x87\x89\x81",
+ nil,
+ },
+ {
+ "tobe;LSB;8",
+ "TOBEORNOTTOBEORTOBEORNOT",
+ "\x54\x9e\x08\x29\xf2\x44\x8a\x93\x27\x54\x04\x12\x34\xb8\xb0\xe0\xc1\x84\x01\x01",
+ nil,
+ },
+ {
+ "tobe;MSB;7",
+ "TOBEORNOTTOBEORTOBEORNOT",
+ "\x54\x4f\x42\x45\x4f\x52\x4e\x4f\x54\x82\x84\x86\x8b\x85\x87\x89\x81",
+ nil,
+ },
+ {
+ "tobe;MSB;8",
+ "TOBEORNOTTOBEORTOBEORNOT",
+ "\x2a\x13\xc8\x44\x52\x79\x48\x9c\x4f\x2a\x40\xa0\x90\x68\x5c\x16\x0f\x09\x80\x80",
+ nil,
+ },
+ {
+ "tobe-truncated;LSB;8",
+ "TOBEORNOTTOBEORTOBEORNOT",
+ "\x54\x9e\x08\x29\xf2\x44\x8a\x93\x27\x54\x04",
+ io.ErrUnexpectedEOF,
+ },
+ // This example comes from https://en.wikipedia.org/wiki/Graphics_Interchange_Format.
+ {
+ "gif;LSB;8",
+ "\x28\xff\xff\xff\x28\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
+ "\x00\x51\xfc\x1b\x28\x70\xa0\xc1\x83\x01\x01",
+ nil,
+ },
+ // This example comes from http://compgroups.net/comp.lang.ruby/Decompressing-LZW-compression-from-PDF-file
+ {
+ "pdf;MSB;8",
+ "-----A---B",
+ "\x80\x0b\x60\x50\x22\x0c\x0c\x85\x01",
+ nil,
+ },
+}
+
+func TestReader(t *testing.T) {
+ var b bytes.Buffer
+ for _, tt := range lzwTests {
+ d := strings.Split(tt.desc, ";")
+ var order Order
+ switch d[1] {
+ case "LSB":
+ order = LSB
+ case "MSB":
+ order = MSB
+ default:
+ t.Errorf("%s: bad order %q", tt.desc, d[1])
+ }
+ litWidth, _ := strconv.Atoi(d[2])
+ rc := NewReader(strings.NewReader(tt.compressed), order, litWidth)
+ defer rc.Close()
+ b.Reset()
+ n, err := io.Copy(&b, rc)
+ s := b.String()
+ if err != nil {
+ if err != tt.err {
+ t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
+ }
+ if err == io.ErrUnexpectedEOF {
+ // Even if the input is truncated, we should still return the
+ // partial decoded result.
+ if n == 0 || !strings.HasPrefix(tt.raw, s) {
+ t.Errorf("got %d bytes (%q), want a non-empty prefix of %q", n, s, tt.raw)
+ }
+ }
+ continue
+ }
+ if s != tt.raw {
+ t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
+ }
+ }
+}
+
+func TestReaderReset(t *testing.T) {
+ var b bytes.Buffer
+ for _, tt := range lzwTests {
+ d := strings.Split(tt.desc, ";")
+ var order Order
+ switch d[1] {
+ case "LSB":
+ order = LSB
+ case "MSB":
+ order = MSB
+ default:
+ t.Errorf("%s: bad order %q", tt.desc, d[1])
+ }
+ litWidth, _ := strconv.Atoi(d[2])
+ rc := NewReader(strings.NewReader(tt.compressed), order, litWidth)
+ defer rc.Close()
+ b.Reset()
+ n, err := io.Copy(&b, rc)
+ b1 := b.Bytes()
+ if err != nil {
+ if err != tt.err {
+ t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
+ }
+ if err == io.ErrUnexpectedEOF {
+ // Even if the input is truncated, we should still return the
+ // partial decoded result.
+ if n == 0 || !strings.HasPrefix(tt.raw, b.String()) {
+ t.Errorf("got %d bytes (%q), want a non-empty prefix of %q", n, b.String(), tt.raw)
+ }
+ }
+ continue
+ }
+
+ b.Reset()
+ rc.(*Reader).Reset(strings.NewReader(tt.compressed), order, litWidth)
+ n, err = io.Copy(&b, rc)
+ b2 := b.Bytes()
+ if err != nil {
+ t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, nil)
+ continue
+ }
+ if !bytes.Equal(b1, b2) {
+ t.Errorf("bytes read were not the same")
+ }
+ }
+}
+
+type devZero struct{}
+
+func (devZero) Read(p []byte) (int, error) {
+ for i := range p {
+ p[i] = 0
+ }
+ return len(p), nil
+}
+
+func TestHiCodeDoesNotOverflow(t *testing.T) {
+ r := NewReader(devZero{}, LSB, 8)
+ d := r.(*Reader)
+ buf := make([]byte, 1024)
+ oldHi := uint16(0)
+ for i := 0; i < 100; i++ {
+ if _, err := io.ReadFull(r, buf); err != nil {
+ t.Fatalf("i=%d: %v", i, err)
+ }
+ // The hi code should never decrease.
+ if d.hi < oldHi {
+ t.Fatalf("i=%d: hi=%d decreased from previous value %d", i, d.hi, oldHi)
+ }
+ oldHi = d.hi
+ }
+}
+
+// TestNoLongerSavingPriorExpansions tests the decoder state when codes other
+// than clear codes continue to be seen after decoder.hi and decoder.width
+// reach their maximum values (4095 and 12), i.e. after we no longer save prior
+// expansions. In particular, it tests seeing the highest possible code, 4095.
+func TestNoLongerSavingPriorExpansions(t *testing.T) {
+ // Iterations is used to calculate how many input bits are needed to get
+ // the decoder.hi and decoder.width values up to their maximum.
+ iterations := []struct {
+ width, n int
+ }{
+ // The final term is 257, not 256, as NewReader initializes d.hi to
+ // d.clear+1 and the clear code is 256.
+ {9, 512 - 257},
+ {10, 1024 - 512},
+ {11, 2048 - 1024},
+ {12, 4096 - 2048},
+ }
+ nCodes, nBits := 0, 0
+ for _, e := range iterations {
+ nCodes += e.n
+ nBits += e.n * e.width
+ }
+ if nCodes != 3839 {
+ t.Fatalf("nCodes: got %v, want %v", nCodes, 3839)
+ }
+ if nBits != 43255 {
+ t.Fatalf("nBits: got %v, want %v", nBits, 43255)
+ }
+
+ // Construct our input of 43255 zero bits (which gets d.hi and d.width up
+ // to 4095 and 12), followed by 0xfff (4095) as 12 bits, followed by 0x101
+ // (EOF) as 12 bits.
+ //
+ // 43255 = 5406*8 + 7, and codes are read in LSB order. The final bytes are
+ // therefore:
+ //
+ // xwwwwwww xxxxxxxx yyyyyxxx zyyyyyyy
+ // 10000000 11111111 00001111 00001000
+ //
+ // or split out:
+ //
+ // .0000000 ........ ........ ........ w = 0x000
+ // 1....... 11111111 .....111 ........ x = 0xfff
+ // ........ ........ 00001... .0001000 y = 0x101
+ //
+ // The 12 'w' bits (not all are shown) form the 3839'th code, with value
+ // 0x000. Just after decoder.read returns that code, d.hi == 4095 and
+ // d.last == 0.
+ //
+ // The 12 'x' bits form the 3840'th code, with value 0xfff or 4095. Just
+ // after decoder.read returns that code, d.hi == 4095 and d.last ==
+ // decoderInvalidCode.
+ //
+ // The 12 'y' bits form the 3841'st code, with value 0x101, the EOF code.
+ //
+ // The 'z' bit is unused.
+ in := make([]byte, 5406)
+ in = append(in, 0x80, 0xff, 0x0f, 0x08)
+
+ r := NewReader(bytes.NewReader(in), LSB, 8)
+ nDecoded, err := io.Copy(io.Discard, r)
+ if err != nil {
+ t.Fatalf("Copy: %v", err)
+ }
+ // nDecoded should be 3841: 3839 literal codes and then 2 decoded bytes
+ // from 1 non-literal code. The EOF code contributes 0 decoded bytes.
+ if nDecoded != int64(nCodes+2) {
+ t.Fatalf("nDecoded: got %v, want %v", nDecoded, nCodes+2)
+ }
+}
+
+func BenchmarkDecoder(b *testing.B) {
+ buf, err := os.ReadFile("../testdata/e.txt")
+ if err != nil {
+ b.Fatal(err)
+ }
+ if len(buf) == 0 {
+ b.Fatalf("test file has no data")
+ }
+
+ getInputBuf := func(buf []byte, n int) []byte {
+ compressed := new(bytes.Buffer)
+ w := NewWriter(compressed, LSB, 8)
+ for i := 0; i < n; i += len(buf) {
+ if len(buf) > n-i {
+ buf = buf[:n-i]
+ }
+ w.Write(buf)
+ }
+ w.Close()
+ return compressed.Bytes()
+ }
+
+ for e := 4; e <= 6; e++ {
+ n := int(math.Pow10(e))
+ b.Run(fmt.Sprint("1e", e), func(b *testing.B) {
+ b.StopTimer()
+ b.SetBytes(int64(n))
+ buf1 := getInputBuf(buf, n)
+ runtime.GC()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ io.Copy(io.Discard, NewReader(bytes.NewReader(buf1), LSB, 8))
+ }
+ })
+ b.Run(fmt.Sprint("1e-Reuse", e), func(b *testing.B) {
+ b.StopTimer()
+ b.SetBytes(int64(n))
+ buf1 := getInputBuf(buf, n)
+ runtime.GC()
+ b.StartTimer()
+ r := NewReader(bytes.NewReader(buf1), LSB, 8)
+ for i := 0; i < b.N; i++ {
+ io.Copy(io.Discard, r)
+ r.Close()
+ r.(*Reader).Reset(bytes.NewReader(buf1), LSB, 8)
+ }
+ })
+ }
+}
diff --git a/src/compress/lzw/writer.go b/src/compress/lzw/writer.go
new file mode 100644
index 0000000..cf06ea8
--- /dev/null
+++ b/src/compress/lzw/writer.go
@@ -0,0 +1,293 @@
+// Copyright 2011 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 lzw
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+)
+
+// A writer is a buffered, flushable writer.
+type writer interface {
+ io.ByteWriter
+ Flush() error
+}
+
+const (
+ // A code is a 12 bit value, stored as a uint32 when encoding to avoid
+ // type conversions when shifting bits.
+ maxCode = 1<<12 - 1
+ invalidCode = 1<<32 - 1
+ // There are 1<<12 possible codes, which is an upper bound on the number of
+ // valid hash table entries at any given point in time. tableSize is 4x that.
+ tableSize = 4 * 1 << 12
+ tableMask = tableSize - 1
+ // A hash table entry is a uint32. Zero is an invalid entry since the
+ // lower 12 bits of a valid entry must be a non-literal code.
+ invalidEntry = 0
+)
+
+// Writer is an LZW compressor. It writes the compressed form of the data
+// to an underlying writer (see NewWriter).
+type Writer struct {
+ // w is the writer that compressed bytes are written to.
+ w writer
+ // order, write, bits, nBits and width are the state for
+ // converting a code stream into a byte stream.
+ order Order
+ write func(*Writer, uint32) error
+ bits uint32
+ nBits uint
+ width uint
+ // litWidth is the width in bits of literal codes.
+ litWidth uint
+ // hi is the code implied by the next code emission.
+ // overflow is the code at which hi overflows the code width.
+ hi, overflow uint32
+ // savedCode is the accumulated code at the end of the most recent Write
+ // call. It is equal to invalidCode if there was no such call.
+ savedCode uint32
+ // err is the first error encountered during writing. Closing the writer
+ // will make any future Write calls return errClosed
+ err error
+ // table is the hash table from 20-bit keys to 12-bit values. Each table
+ // entry contains key<<12|val and collisions resolve by linear probing.
+ // The keys consist of a 12-bit code prefix and an 8-bit byte suffix.
+ // The values are a 12-bit code.
+ table [tableSize]uint32
+}
+
+// writeLSB writes the code c for "Least Significant Bits first" data.
+func (w *Writer) writeLSB(c uint32) error {
+ w.bits |= c << w.nBits
+ w.nBits += w.width
+ for w.nBits >= 8 {
+ if err := w.w.WriteByte(uint8(w.bits)); err != nil {
+ return err
+ }
+ w.bits >>= 8
+ w.nBits -= 8
+ }
+ return nil
+}
+
+// writeMSB writes the code c for "Most Significant Bits first" data.
+func (w *Writer) writeMSB(c uint32) error {
+ w.bits |= c << (32 - w.width - w.nBits)
+ w.nBits += w.width
+ for w.nBits >= 8 {
+ if err := w.w.WriteByte(uint8(w.bits >> 24)); err != nil {
+ return err
+ }
+ w.bits <<= 8
+ w.nBits -= 8
+ }
+ return nil
+}
+
+// errOutOfCodes is an internal error that means that the writer has run out
+// of unused codes and a clear code needs to be sent next.
+var errOutOfCodes = errors.New("lzw: out of codes")
+
+// incHi increments e.hi and checks for both overflow and running out of
+// unused codes. In the latter case, incHi sends a clear code, resets the
+// writer state and returns errOutOfCodes.
+func (w *Writer) incHi() error {
+ w.hi++
+ if w.hi == w.overflow {
+ w.width++
+ w.overflow <<= 1
+ }
+ if w.hi == maxCode {
+ clear := uint32(1) << w.litWidth
+ if err := w.write(w, clear); err != nil {
+ return err
+ }
+ w.width = w.litWidth + 1
+ w.hi = clear + 1
+ w.overflow = clear << 1
+ for i := range w.table {
+ w.table[i] = invalidEntry
+ }
+ return errOutOfCodes
+ }
+ return nil
+}
+
+// Write writes a compressed representation of p to w's underlying writer.
+func (w *Writer) Write(p []byte) (n int, err error) {
+ if w.err != nil {
+ return 0, w.err
+ }
+ if len(p) == 0 {
+ return 0, nil
+ }
+ if maxLit := uint8(1<<w.litWidth - 1); maxLit != 0xff {
+ for _, x := range p {
+ if x > maxLit {
+ w.err = errors.New("lzw: input byte too large for the litWidth")
+ return 0, w.err
+ }
+ }
+ }
+ n = len(p)
+ code := w.savedCode
+ if code == invalidCode {
+ // This is the first write; send a clear code.
+ // https://www.w3.org/Graphics/GIF/spec-gif89a.txt Appendix F
+ // "Variable-Length-Code LZW Compression" says that "Encoders should
+ // output a Clear code as the first code of each image data stream".
+ //
+ // LZW compression isn't only used by GIF, but it's cheap to follow
+ // that directive unconditionally.
+ clear := uint32(1) << w.litWidth
+ if err := w.write(w, clear); err != nil {
+ return 0, err
+ }
+ // After the starting clear code, the next code sent (for non-empty
+ // input) is always a literal code.
+ code, p = uint32(p[0]), p[1:]
+ }
+loop:
+ for _, x := range p {
+ literal := uint32(x)
+ key := code<<8 | literal
+ // If there is a hash table hit for this key then we continue the loop
+ // and do not emit a code yet.
+ hash := (key>>12 ^ key) & tableMask
+ for h, t := hash, w.table[hash]; t != invalidEntry; {
+ if key == t>>12 {
+ code = t & maxCode
+ continue loop
+ }
+ h = (h + 1) & tableMask
+ t = w.table[h]
+ }
+ // Otherwise, write the current code, and literal becomes the start of
+ // the next emitted code.
+ if w.err = w.write(w, code); w.err != nil {
+ return 0, w.err
+ }
+ code = literal
+ // Increment e.hi, the next implied code. If we run out of codes, reset
+ // the writer state (including clearing the hash table) and continue.
+ if err1 := w.incHi(); err1 != nil {
+ if err1 == errOutOfCodes {
+ continue
+ }
+ w.err = err1
+ return 0, w.err
+ }
+ // Otherwise, insert key -> e.hi into the map that e.table represents.
+ for {
+ if w.table[hash] == invalidEntry {
+ w.table[hash] = (key << 12) | w.hi
+ break
+ }
+ hash = (hash + 1) & tableMask
+ }
+ }
+ w.savedCode = code
+ return n, nil
+}
+
+// Close closes the Writer, flushing any pending output. It does not close
+// w's underlying writer.
+func (w *Writer) Close() error {
+ if w.err != nil {
+ if w.err == errClosed {
+ return nil
+ }
+ return w.err
+ }
+ // Make any future calls to Write return errClosed.
+ w.err = errClosed
+ // Write the savedCode if valid.
+ if w.savedCode != invalidCode {
+ if err := w.write(w, w.savedCode); err != nil {
+ return err
+ }
+ if err := w.incHi(); err != nil && err != errOutOfCodes {
+ return err
+ }
+ } else {
+ // Write the starting clear code, as w.Write did not.
+ clear := uint32(1) << w.litWidth
+ if err := w.write(w, clear); err != nil {
+ return err
+ }
+ }
+ // Write the eof code.
+ eof := uint32(1)<<w.litWidth + 1
+ if err := w.write(w, eof); err != nil {
+ return err
+ }
+ // Write the final bits.
+ if w.nBits > 0 {
+ if w.order == MSB {
+ w.bits >>= 24
+ }
+ if err := w.w.WriteByte(uint8(w.bits)); err != nil {
+ return err
+ }
+ }
+ return w.w.Flush()
+}
+
+// Reset clears the Writer's state and allows it to be reused again
+// as a new Writer.
+func (w *Writer) Reset(dst io.Writer, order Order, litWidth int) {
+ *w = Writer{}
+ w.init(dst, order, litWidth)
+}
+
+// NewWriter creates a new io.WriteCloser.
+// Writes to the returned io.WriteCloser are compressed and written to w.
+// It is the caller's responsibility to call Close on the WriteCloser when
+// finished writing.
+// The number of bits to use for literal codes, litWidth, must be in the
+// range [2,8] and is typically 8. Input bytes must be less than 1<<litWidth.
+//
+// It is guaranteed that the underlying type of the returned io.WriteCloser
+// is a *Writer.
+func NewWriter(w io.Writer, order Order, litWidth int) io.WriteCloser {
+ return newWriter(w, order, litWidth)
+}
+
+func newWriter(dst io.Writer, order Order, litWidth int) *Writer {
+ w := new(Writer)
+ w.init(dst, order, litWidth)
+ return w
+}
+
+func (w *Writer) init(dst io.Writer, order Order, litWidth int) {
+ switch order {
+ case LSB:
+ w.write = (*Writer).writeLSB
+ case MSB:
+ w.write = (*Writer).writeMSB
+ default:
+ w.err = errors.New("lzw: unknown order")
+ return
+ }
+ if litWidth < 2 || 8 < litWidth {
+ w.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
+ return
+ }
+ bw, ok := dst.(writer)
+ if !ok && dst != nil {
+ bw = bufio.NewWriter(dst)
+ }
+ w.w = bw
+ lw := uint(litWidth)
+ w.order = order
+ w.width = 1 + lw
+ w.litWidth = lw
+ w.hi = 1<<lw + 1
+ w.overflow = 1 << (lw + 1)
+ w.savedCode = invalidCode
+}
diff --git a/src/compress/lzw/writer_test.go b/src/compress/lzw/writer_test.go
new file mode 100644
index 0000000..edf683a
--- /dev/null
+++ b/src/compress/lzw/writer_test.go
@@ -0,0 +1,238 @@
+// Copyright 2011 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 lzw
+
+import (
+ "bytes"
+ "fmt"
+ "internal/testenv"
+ "io"
+ "math"
+ "os"
+ "runtime"
+ "testing"
+)
+
+var filenames = []string{
+ "../testdata/gettysburg.txt",
+ "../testdata/e.txt",
+ "../testdata/pi.txt",
+}
+
+// testFile tests that compressing and then decompressing the given file with
+// the given options yields equivalent bytes to the original file.
+func testFile(t *testing.T, fn string, order Order, litWidth int) {
+ // Read the file, as golden output.
+ golden, err := os.Open(fn)
+ if err != nil {
+ t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
+ return
+ }
+ defer golden.Close()
+
+ // Read the file again, and push it through a pipe that compresses at the write end, and decompresses at the read end.
+ raw, err := os.Open(fn)
+ if err != nil {
+ t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
+ return
+ }
+
+ piper, pipew := io.Pipe()
+ defer piper.Close()
+ go func() {
+ defer raw.Close()
+ defer pipew.Close()
+ lzww := NewWriter(pipew, order, litWidth)
+ defer lzww.Close()
+ var b [4096]byte
+ for {
+ n, err0 := raw.Read(b[:])
+ if err0 != nil && err0 != io.EOF {
+ t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
+ return
+ }
+ _, err1 := lzww.Write(b[:n])
+ if err1 != nil {
+ t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
+ return
+ }
+ if err0 == io.EOF {
+ break
+ }
+ }
+ }()
+ lzwr := NewReader(piper, order, litWidth)
+ defer lzwr.Close()
+
+ // Compare the two.
+ b0, err0 := io.ReadAll(golden)
+ b1, err1 := io.ReadAll(lzwr)
+ if err0 != nil {
+ t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0)
+ return
+ }
+ if err1 != nil {
+ t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1)
+ return
+ }
+ if len(b1) != len(b0) {
+ t.Errorf("%s (order=%d litWidth=%d): length mismatch %d != %d", fn, order, litWidth, len(b1), len(b0))
+ return
+ }
+ for i := 0; i < len(b0); i++ {
+ if b1[i] != b0[i] {
+ t.Errorf("%s (order=%d litWidth=%d): mismatch at %d, 0x%02x != 0x%02x\n", fn, order, litWidth, i, b1[i], b0[i])
+ return
+ }
+ }
+}
+
+func TestWriter(t *testing.T) {
+ for _, filename := range filenames {
+ for _, order := range [...]Order{LSB, MSB} {
+ // The test data "2.71828 etcetera" is ASCII text requiring at least 6 bits.
+ for litWidth := 6; litWidth <= 8; litWidth++ {
+ if filename == "../testdata/gettysburg.txt" && litWidth == 6 {
+ continue
+ }
+ testFile(t, filename, order, litWidth)
+ }
+ }
+ if testing.Short() && testenv.Builder() == "" {
+ break
+ }
+ }
+}
+
+func TestWriterReset(t *testing.T) {
+ for _, order := range [...]Order{LSB, MSB} {
+ t.Run(fmt.Sprintf("Order %d", order), func(t *testing.T) {
+ for litWidth := 6; litWidth <= 8; litWidth++ {
+ t.Run(fmt.Sprintf("LitWidth %d", litWidth), func(t *testing.T) {
+ var data []byte
+ if litWidth == 6 {
+ data = []byte{1, 2, 3}
+ } else {
+ data = []byte(`lorem ipsum dolor sit amet`)
+ }
+ var buf bytes.Buffer
+ w := NewWriter(&buf, order, litWidth)
+ if _, err := w.Write(data); err != nil {
+ t.Errorf("write: %v: %v", string(data), err)
+ }
+
+ if err := w.Close(); err != nil {
+ t.Errorf("close: %v", err)
+ }
+
+ b1 := buf.Bytes()
+ buf.Reset()
+
+ w.(*Writer).Reset(&buf, order, litWidth)
+
+ if _, err := w.Write(data); err != nil {
+ t.Errorf("write: %v: %v", string(data), err)
+ }
+
+ if err := w.Close(); err != nil {
+ t.Errorf("close: %v", err)
+ }
+ b2 := buf.Bytes()
+
+ if !bytes.Equal(b1, b2) {
+ t.Errorf("bytes written were not same")
+ }
+ })
+ }
+ })
+ }
+}
+
+func TestWriterReturnValues(t *testing.T) {
+ w := NewWriter(io.Discard, LSB, 8)
+ n, err := w.Write([]byte("asdf"))
+ if n != 4 || err != nil {
+ t.Errorf("got %d, %v, want 4, nil", n, err)
+ }
+}
+
+func TestSmallLitWidth(t *testing.T) {
+ w := NewWriter(io.Discard, LSB, 2)
+ if _, err := w.Write([]byte{0x03}); err != nil {
+ t.Fatalf("write a byte < 1<<2: %v", err)
+ }
+ if _, err := w.Write([]byte{0x04}); err == nil {
+ t.Fatal("write a byte >= 1<<2: got nil error, want non-nil")
+ }
+}
+
+func TestStartsWithClearCode(t *testing.T) {
+ // A literal width of 7 bits means that the code width starts at 8 bits,
+ // which makes it easier to visually inspect the output (provided that the
+ // output is short so codes don't get longer). Each byte is a code:
+ // - ASCII bytes are literal codes,
+ // - 0x80 is the clear code,
+ // - 0x81 is the end code.
+ // - 0x82 and above are copy codes (unused in this test case).
+ for _, empty := range []bool{false, true} {
+ var buf bytes.Buffer
+ w := NewWriter(&buf, LSB, 7)
+ if !empty {
+ w.Write([]byte("Hi"))
+ }
+ w.Close()
+ got := buf.String()
+
+ want := "\x80\x81"
+ if !empty {
+ want = "\x80Hi\x81"
+ }
+
+ if got != want {
+ t.Errorf("empty=%t: got %q, want %q", empty, got, want)
+ }
+ }
+}
+
+func BenchmarkEncoder(b *testing.B) {
+ buf, err := os.ReadFile("../testdata/e.txt")
+ if err != nil {
+ b.Fatal(err)
+ }
+ if len(buf) == 0 {
+ b.Fatalf("test file has no data")
+ }
+
+ for e := 4; e <= 6; e++ {
+ n := int(math.Pow10(e))
+ buf0 := buf
+ buf1 := make([]byte, n)
+ for i := 0; i < n; i += len(buf0) {
+ if len(buf0) > n-i {
+ buf0 = buf0[:n-i]
+ }
+ copy(buf1[i:], buf0)
+ }
+ buf0 = nil
+ runtime.GC()
+ b.Run(fmt.Sprint("1e", e), func(b *testing.B) {
+ b.SetBytes(int64(n))
+ for i := 0; i < b.N; i++ {
+ w := NewWriter(io.Discard, LSB, 8)
+ w.Write(buf1)
+ w.Close()
+ }
+ })
+ b.Run(fmt.Sprint("1e-Reuse", e), func(b *testing.B) {
+ b.SetBytes(int64(n))
+ w := NewWriter(io.Discard, LSB, 8)
+ for i := 0; i < b.N; i++ {
+ w.Write(buf1)
+ w.Close()
+ w.(*Writer).Reset(io.Discard, LSB, 8)
+ }
+ })
+ }
+}
diff --git a/src/compress/testdata/e.txt b/src/compress/testdata/e.txt
new file mode 100644
index 0000000..5ca186f
--- /dev/null
+++ b/src/compress/testdata/e.txt
@@ -0,0 +1 @@
+2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354021234078498193343210681701210056278802351930332247450158539047304199577770935036604169973297250886876966403555707162268447162560798826517871341951246652010305921236677194325278675398558944896970964097545918569563802363701621120477427228364896134225164450781824423529486363721417402388934412479635743702637552944483379980161254922785092577825620926226483262779333865664816277251640191059004916449982893150566047258027786318641551956532442586982946959308019152987211725563475463964479101459040905862984967912874068705048958586717479854667757573205681288459205413340539220001137863009455606881667400169842055804033637953764520304024322566135278369511778838638744396625322498506549958862342818997077332761717839280349465014345588970719425863987727547109629537415211151368350627526023264847287039207643100595841166120545297030236472549296669381151373227536450988890313602057248176585118063036442812314965507047510254465011727211555194866850800368532281831521960037356252794495158284188294787610852639813955990067376482922443752871846245780361929819713991475644882626039033814418232625150974827987779964373089970388867782271383605772978824125611907176639465070633045279546618550966661856647097113444740160704626215680717481877844371436988218559670959102596862002353718588748569652200050311734392073211390803293634479727355955277349071783793421637012050054513263835440001863239914907054797780566978533580489669062951194324730995876552368128590413832411607226029983305353708761389396391779574540161372236187893652605381558415871869255386061647798340254351284396129460352913325942794904337299085731580290958631382683291477116396337092400316894586360606458459251269946557248391865642097526850823075442545993769170419777800853627309417101634349076964237222943523661255725088147792231519747780605696725380171807763603462459278778465850656050780844211529697521890874019660906651803516501792504619501366585436632712549639908549144200014574760819302212066024330096412704894390397177195180699086998606636583232278709376502260149291011517177635944602023249300280401867723910288097866605651183260043688508817157238669842242201024950551881694803221002515426494639812873677658927688163598312477886520141174110913601164995076629077943646005851941998560162647907615321038727557126992518275687989302761761146162549356495903798045838182323368612016243736569846703785853305275833337939907521660692380533698879565137285593883499894707416181550125397064648171946708348197214488898790676503795903669672494992545279033729636162658976039498576741397359441023744329709355477982629614591442936451428617158587339746791897571211956187385783644758448423555581050025611492391518893099463428413936080383091662818811503715284967059741625628236092168075150177725387402564253470879089137291722828611515915683725241630772254406337875931059826760944203261924285317018781772960235413060672136046000389661093647095141417185777014180606443636815464440053316087783143174440811949422975599314011888683314832802706553833004693290115744147563139997221703804617092894579096271662260740718749975359212756084414737823303270330168237193648002173285734935947564334129943024850235732214597843282641421684878721673367010615094243456984401873312810107945127223737886126058165668053714396127888732527373890392890506865324138062796025930387727697783792868409325365880733988457218746021005311483351323850047827169376218004904795597959290591655470505777514308175112698985188408718564026035305583737832422924185625644255022672155980274012617971928047139600689163828665277009752767069777036439260224372841840883251848770472638440379530166905465937461619323840363893131364327137688841026811219891275223056256756254701725086349765367288605966752740868627407912856576996313789753034660616669804218267724560530660773899624218340859882071864682623215080288286359746839654358856685503773131296587975810501214916207656769950659715344763470320853215603674828608378656803073062657633469774295634643716709397193060876963495328846833613038829431040800296873869117066666146800015121143442256023874474325250769387077775193299942137277211258843608715834835626961661980572526612206797540621062080649882918454395301529982092503005498257043390553570168653120526495614857249257386206917403695213533732531666345466588597286659451136441370331393672118569553952108458407244323835586063106806964924851232632699514603596037297253198368423363904632136710116192821711150282801604488058802382031981493096369596735832742024988245684941273860566491352526706046234450549227581151709314921879592718001940968866986837037302200475314338181092708030017205935530520700706072233999463990571311587099635777359027196285061146514837526209565346713290025994397663114545902685898979115837093419370441155121920117164880566945938131183843765620627846310490346293950029458341164824114969758326011800731699437393506966295712410273239138741754923071862454543222039552735295240245903805744502892246886285336542213815722131163288112052146489805180092024719391710555390113943316681515828843687606961102505171007392762385553386272553538830960671644662370922646809671254061869502143176211668140097595281493907222601112681153108387317617323235263605838173151034595736538223534992935822836851007810884634349983518404451704270189381994243410090575376257767571118090088164183319201962623416288166521374717325477727783488774366518828752156685719506371936565390389449366421764003121527870222366463635755503565576948886549500270853923617105502131147413744106134445544192101336172996285694899193369184729478580729156088510396781959429833186480756083679551496636448965592948187851784038773326247051945050419847742014183947731202815886845707290544057510601285258056594703046836344592652552137008068752009593453607316226118728173928074623094685367823106097921599360019946237993434210687813497346959246469752506246958616909178573976595199392993995567542714654910456860702099012606818704984178079173924071945996323060254707901774527513186809982284730860766536866855516467702911336827563107223346726113705490795365834538637196235856312618387156774118738527722922594743373785695538456246801013905727871016512966636764451872465653730402443684140814488732957847348490003019477888020460324660842875351848364959195082888323206522128104190448047247949291342284951970022601310430062410717971502793433263407995960531446053230488528972917659876016667811937932372453857209607582277178483361613582612896226118129455927462767137794487586753657544861407611931125958512655759734573015333642630767985443385761715333462325270572005303988289499034259566232975782488735029259166825894456894655992658454762694528780516501720674785417887982276806536650641910973434528878338621726156269582654478205672987756426325321594294418039943217000090542650763095588465895171709147607437136893319469090981904501290307099566226620303182649365733698419555776963787624918852865686607600566025605445711337286840205574416030837052312242587223438854123179481388550075689381124935386318635287083799845692619981794523364087429591180747453419551420351726184200845509170845682368200897739455842679214273477560879644279202708312150156406341341617166448069815483764491573900121217041547872591998943825364950514771379399147205219529079396137621107238494290616357604596231253506068537651423115349665683715116604220796394466621163255157729070978473156278277598788136491951257483328793771571459091064841642678309949723674420175862269402159407924480541255360431317992696739157542419296607312393763542139230617876753958711436104089409966089471418340698362993675362621545247298464213752891079884381306095552622720837518629837066787224430195793793786072107254277289071732854874374355781966511716618330881129120245204048682200072344035025448202834254187884653602591506445271657700044521097735585897622655484941621714989532383421600114062950718490427789258552743035221396835679018076406042138307308774460170842688272261177180842664333651780002171903449234264266292261456004337383868335555343453004264818473989215627086095650629340405264943244261445665921291225648893569655009154306426134252668472594914314239398845432486327461842846655985332312210466259890141712103446084271616619001257195870793217569698544013397622096749454185407118446433946990162698351607848924514058940946395267807354579700307051163682519487701189764002827648414160587206184185297189154019688253289309149665345753571427318482016384644832499037886069008072709327673127581966563941148961716832980455139729506687604740915420428429993541025829113502241690769431668574242522509026939034814856451303069925199590436384028429267412573422447765584177886171737265462085498294498946787350929581652632072258992368768457017823038096567883112289305809140572610865884845873101658151167533327674887014829167419701512559782572707406431808601428149024146780472327597684269633935773542930186739439716388611764209004068663398856841681003872389214483176070116684503887212364367043314091155733280182977988736590916659612402021778558854876176161989370794380056663364884365089144805571039765214696027662583599051987042300179465536788567430285974600143785483237068701190078499404930918919181649327259774030074879681484882342932023012128032327460392219687528340516906974194257614673978110715464186273369091584973185011183960482533518748438923177292613543024932562896371361977285456622924461644497284597867711574125670307871885109336344480149675240618536569532074170533486782754827815415561966911055101472799040386897220465550833170782394808785990501947563108984124144672821865459971596639015641941751820935932616316888380132758752601460507676098392625726411120135288591317848299475682472564885533357279772205543568126302535748216585414000805314820697137262149755576051890481622376790414926742600071045922695314835188137463887104273544767623577933993970632396604969145303273887874557905934937772320142954803345000695256980935282887783710670585567749481373858630385762823040694005665340584887527005308832459182183494318049834199639981458773435863115940570443683515285383609442955964360676090221741896883548131643997437764158365242234642619597390455450680695232850751868719449064767791886720306418630751053512149851051207313846648717547518382979990189317751550639981016466414592102406838294603208535554058147159273220677567669213664081505900806952540610628536408293276621931939933861623836069111767785448236129326858199965239275488427435414402884536455595124735546139403154952097397051896240157976832639450633230452192645049651735466775699295718989690470902730288544945416699791992948038254980285946029052763145580316514066229171223429375806143993484914362107993576737317948964252488813720435579287511385856973381976083524423240466778020948399639946684833774706725483618848273000648319163826022110555221246733323184463005504481849916996622087746140216157021029603318588727333298779352570182393861244026868339555870607758169954398469568540671174444932479519572159419645863736126915526457574786985964242176592896862383506370433939811671397544736228625506803682664135541448048997721373174119199970017293907303350869020922519124447393278376156321810842898207706974138707053266117683698647741787180202729412982310888796831880854367327806879771659111654224453806625861711729498038248879986504061563975629936962809358189761491017145343556659542757064194408833816841111166200759787244137082333917886114708228657531078536674695018462140736493917366254937783014074302668422150335117736471853872324040421037907750266020114814935482228916663640782450166815341213505278578539332606110249802273093636740213515386431693015267460536064351732154701091440650878823636764236831187390937464232609021646365627553976834019482932795750624399645272578624400375983422050808935129023122475970644105678361870877172333555465482598906861201410107222465904008553798235253885171623518256518482203125214950700378300411216212126052726059944320443056274522916128891766814160639131235975350390320077529587392412476451850809163911459296071156344204347133544720981178461451077872399140606290228276664309264900592249810291068759434533858330391178747575977065953570979640012224092199031158229259667913153991561438070129260780197022589662923368154312499412259460023399472228171056603931877226800493833148980338548909468685130789292064242819174795866199944411196208730498064385006852620258432842085582338566936649849720817046135376163584015342840674118587581546514598270228676671855309311923340191286170613364873183197560812569460089402953094429119590295968563923037689976327462283900735457144596414108229285922239332836210192822937243590283003884445701383771632056518351970100115722010956997890484964453434612129224964732356126321951155701565824427661599326463155806672053127596948538057364208384918887095176052287817339462747644656858900936266123311152910816041524100214195937349786431661556732702792109593543055579732660554677963552005378304619540636971842916168582734122217145885870814274090248185446421774876925093328785670674677381226752831653559245204578070541352576903253522738963847495646255940378924925007624386893776475310102323746733771474581625530698032499033676455430305274561512961214585944432150749051491453950981001388737926379964873728396416897555132275962011838248650746985492038097691932606437608743209385602815642849756549307909733854185583515789409814007691892389063090542534883896831762904120212949167195811935791203162514344096503132835216728021372415947344095498316138322505486708172221475138425166790445416617303200820330902895488808516797258495813407132180533988828139346049850532340472595097214331492586604248511405819579711564191458842833000525684776874305916390494306871343118796189637475503362820939949343690321031976898112055595369465424704173323895394046035325396758354395350516720261647961347790912327995264929045151148307923369382166010702872651938143844844532639517394110131152502750465749343063766541866128915264446926222884366299462732467958736383501937142786471398054038215513463223702071533134887083174146591492406359493020921122052610312390682941345696785958518393491382340884274312419099152870804332809132993078936867127413922890033069995875921815297612482409116951587789964090352577345938248232053055567238095022266790439614231852991989181065554412477204508510210071522352342792531266930108270633942321762570076323139159349709946933241013908779161651226804414809765618979735043151396066913258379033748620836695475083280318786707751177525663963479259219733577949555498655214193398170268639987388347010255262052312317215254062571636771270010760912281528326508984359568975961038372157726831170734552250194121701541318793651818502020877326906133592182000762327269503283827391243828198170871168108951187896746707073377869592565542713340052326706040004348843432902760360498027862160749469654989210474443927871934536701798673920803845633723311983855862638008516345597194441994344624761123844617615736242015935078520825600604101556889899501732554337298073561699861101908472096600708320280569917042590103876928658336557728758684250492690370934262028022399861803400211320742198642917383679176232826444645756330336556777374808644109969141827774253417010988435853189339175934511574023847292909015468559163792696196841000676598399744972047287881831200233383298030567865480871476464512824264478216644266616732096012564794514827125671326697067367144617795643752391742928503987022583734069852309190464967260243411270345611114149835783901793499713790913696706497637127248466613279908254305449295528594932793818341607827091326680865655921102733746700132583428715240835661522165574998431236278287106649401564670141943713823863454729606978693335973109537126499416282656463708490580151538205338326511289504938566468752921135932220265681856418260827538790002407915892646028490894922299966167437731347776134150965262448332709343898412056926145108857812249139616912534202918139898683901335795857624435194008943955180554746554000051766240202825944828833811886381749594284892013520090951007864941868256009273977667585642598378587497776669563350170748579027248701370264203283965756348010818356182372177082236423186591595883669487322411726504487268392328453010991677518376831599821263237123854357312681202445175401852132663740538802901249728180895021553100673598184430429105288459323064725590442355960551978839325930339572934663055160430923785677229293537208416693134575284011873746854691620648991164726909428982971065606801805807843600461866223562874591385185904416250663222249561448724413813849763797102676020845531824111963927941069619465426480006761727618115630063644321116224837379105623611358836334550102286170517890440570419577859833348463317921904494652923021469259756566389965893747728751393377105569802455757436190501772466214587592374418657530064998056688376964229825501195065837843125232135309371235243969149662310110328243570065781487677299160941153954063362752423712935549926713485031578238899567545287915578420483105749330060197958207739558522807307048950936235550769837881926357141779338750216344391014187576711938914416277109602859415809719913429313295145924373636456473035037374538503489286113141638094752301745088784885645741275003353303416138096560043105860548355773946625033230034341587814634602169235079216111013148948281895391028916816328709309713184139815427678818067628650978085718262117003140003377301581536334149093237034703637513354537634521050370995452942055232078817449370937677056009306353645510913481627378204985657055608784211964039972344556458607689515569686899384896439195225232309703301037277227710870564912966121061494072782442033414057441446459968236966118878411656290355117839944070961772567164919790168195234523807446299877664824873753313018142763910519234685081979001796519907050490865237442841652776611425351538665162781316090964802801234493372427866930894827913465443931965254154829494577875758599482099181824522449312077768250830768282335001597040419199560509705364696473142448453825888112602753909548852639708652339052941829691802357120545328231809270356491743371932080628731303589640570873779967845174740515317401384878082881006046388936711640477755985481263907504747295012609419990373721246201677030517790352952793168766305099837441859803498821239340919805055103821539827677291373138006715339240126954586376422065097810852907639079727841301764553247527073788764069366420012194745702358295481365781809867944020220280822637957006755393575808086318932075864444206644691649334467698180811716568665213389686173592450920801465312529777966137198695916451869432324246404401672381978020728394418264502183131483366019384891972317817154372192103946638473715630226701801343515930442853848941825678870721238520597263859224934763623122188113706307506918260109689069251417142514218153491532129077723748506635489170892850760234351768218355008829647410655814882049239533702270536705630750317499788187009989251020178015601042277836283644323729779929935160925884515772055232896978333126427671291093993103773425910592303277652667641874842441076564447767097790392324958416348527735171981064673837142742974468992320406932506062834468937543016787815320616009057693404906146176607094380110915443261929000745209895959201159412324102274845482605404361871836330268992858623582145643879695210235266673372434423091577183277565800211928270391042391966426911155333594569685782817020325495552528875464466074620294766116004435551604735044292127916358748473501590215522120388281168021413865865168464569964810015633741255098479730138656275460161279246359783661480163871602794405482710196290774543628092612567507181773641749763254436773503632580004042919906963117397787875081560227368824967077635559869284901628768699628053790181848148810833946900016380791075960745504688912686792812391148880036720729730801354431325347713094186717178607522981373539126772812593958220524289991371690685650421575056729991274177149279608831502358697816190894908487717722503860872618384947939757440664912760518878124233683125467278331513186758915668300679210215947336858591201395360301678110413444411030903388761520488296909104689167671555373346622545575975202624771242796225983278405833585897671474205724047439720232895903726148688388003174146490203843590358527993123871042845981608996101945691646983837718267264685264869172948414153004604004299585035164101899027529366867431834955447458124140190754681607770977920579383895378192128847409929537040546962226547278807248685508046571043123854873351653070570784584243335550958221912862797205455466267099131902370311779690892786623112661337671178512943059323281605826535623848164192144732543731002062738466812351691016359252588256806438946389880872735284406462208149513862275239938938734905082625472417781702582044129853760499827899020083498387362992498125742354568439023012261733665820546785671147973065077035475620567428300187473019197310881157516777005071432012726354601912460800451608108641835539669946936947322271670748972850464195392966434725254724357659192969949061670189061433616907056148280980363243454128229968275980226694045642181328624517549652147221620839824594576613342710564957193564431561774500828376935700995419541839029151033187933907614207467028867968594985439789457300768939890070073924697461812855764662265412913204052279071212820653775058280040897163467163709024906774736309136904002615646432159560910851092445162454420141442641660181385990017417408244245378610158433361777292580611159192008414091888191208858207627011483671760749046980914443057262211104583300789331698191603917150622792986282709446275915009683226345073725451366858172483498470080840163868209726371345205439802277866337293290829914010645589761697455978409211409167684020269370229231743334499986901841510888993165125090001163719114994852024821586396216294981753094623047604832399379391002142532996476235163569009445086058091202459904612118623318278614464727795523218635916551883057930657703331498510068357135624341881884405780028844018129031378653794869614630467726914552953690154167025838032477842272417994513653582260971652588356712133519546838335349801503269359798167463231847628306340588324731228951257944267639877946713121042763380872695738609314631539148548792514028885025189788076023838995615684850391995855029256054176767663145354058496296796781349420116003325874431438746248313850214980401681940795687219268462617287403480967931949965604299190281810597603263251746405016454606266765529010639868703668263299050577706266397868453584384057673298268163448646707439990917504018892319267557518354054956017732907127219134577524905771512773358423314008356080926962298894163047287780054743798498545562870729968407382937218623831766524716090967192007237658894226186550487552614557855898773008703234726418384831040394818743616224455286163287628541175946460497027724490799275146445792982549802258601001772437840167723166802004162547244179415547810554178036773553354467030326469619447560812831933095679685582771932031205941616693902049665352189672822671972640029493307384717544753761937017882976382487233361813499414541694736549254840633793674361541081593464960431603544354737728802361047743115330785159902977771499610274627769759612488879448609863349422852847651310277926279743981957617505591300993377368240510902583759345170015340522266144077237050890044496613295859536020556034009492820943862994618834790932894161098856594954213114335608810239423706087108026465913203560121875933791639666437282836752328391688865373751335794859860107569374889645657187292540448508624449947816273842517229343960137212406286783636675845331904743954740664015260871940915743955282773904303868772728262065663129387459875317749973799293043294371763801856280061141619563942414312254397099163565102848315765427037906837175764870230052388197498746636856292655058222887713221781440489538099681072143012394693530931524054081215705402274414521876541901428386744260011889041724570537470755550581632831687247110220353727166112304857340460879272501694701067831178927095527253222125224361673343366384756590949728221809418684074238351567868893421148203905824224324264643630201441787982022116248471657468291146315407563770222740135841109076078464780070182766336227978104546331131294044833570134869585165267459515187680033395522410548181767867772152798270250117195816577603549732923724732067853690257536233971216884390878879262188202305529937132397194333083536231248870386416194361506529551267334207198502259771408638122015980894363561808597010080081622557455039101321981979045520049618583777721048046635533806616517023595097133203631578945644487800945620369784973459902004606886572701865867757842758530645706617127194967371083950603267501532435909029491516973738110897934782297684100117657987098185725131372267749706609250481876835516003714638685918913011736805218743265426063700710595364425062760458252336880552521181566417553430681181548267844169315284408461087588214317641649835663127518728182948655658524206852221830755306118393326934164459415342651778653397980580828158806300749952897558204686612590853678738603318442905510689778698417735603118111677563872589911516803236547002987989628986181014596471307916144369564690909518788574398821730583884980809523077569358851616027719521488998358632323127308909861560777386006984035267826785387215920936255817889813416247486456433211043194821421299793188104636399541496539441501383868748384870224681829391860319598667962363489309283087840712400431022706137591368056518861313458307990705003607588327248867879324093380071864152853317943535073401891193638546730000660453783784472469288830546979000131248952100446949032058838294923613919284305249167833012980192255157050378521810552961623637523647962685751660066539364142273063001648652613891842243501797455993616794063303522111829071597538821839777552812981538570168702202620274678647916644030729018445497956399844836807851997088201407769199261674991148329821854382718946282165387064858588646221611410343570342878862979083418871606214430014533275029715104673156021000043869510583773779766003460887624861640938645252177935289947578496255243925598620521409052346250847830487046492688313289470553891357290706967599556298586669559721686506052072801342104355762779184021797626656484580261591407173477009039475168017709900129391137881248534255949312866653465033728846390649968460644741907524313323903404908195233044389559060547854954620263256676813262435925020249516275607080900436460421497025691488555265022810327762115842282433269528629137662675481993546118143913367579700141255870143319434764035725376914388899683088262844616425575034001428982557620386364384137906519612917777354183694676232982904981261717676191554292570438432239918482261744350470199171258214687683172646078959690569981353264435973965173473319484798758064137926885413552523275720457329477215706850016950046959758389373527538622664943456437071610511521617176237598050900553232154896062817794302268640579555845730600598376482703339859420098582351400179507104569019191359062304102336798080907240196312675268916362136351032648077232914950859151265812143823371072949148088472355286394195993455684156344577951727033374238129903260198160571971183950662758220321837136059718025940870615534713104482272716848395524105913605919812444978458110854511231668173534838253724825347636777581712867205865148285317273569069839935110763432091319780314031658897379628301178409806410175016511072932907832177487566289310650383806093372841399226733384778203302020700517188941706465146238366720632742644336612174011766914919235570905644803016342294301837655263108450172510307540942604409687066288066265900569082451407632599158164499361455172452057020443093722305550217222299706209749268609762787409626448772056043078634808885709143464793241536214303199965695610753570417207285334250171325558818113295504095217830139465216436594262960768570585698507157151317262928960072587601564840556088613165411835958628710665496282599535127193244635791046554389165150954187306071015034430609582302257455974944275067630926322529966338219395202927917973247094559691016402983683080426309910481567503623509654924302589575273521412445149542462972258510120707802110188106722347972579330653187713438466713807546383471635428854957610942841898601794658721444495198801550804042506452191484989920400007310672369944655246020908767882300064337725657385010969899058191290957079866699453765080407917852438222041070599278889267745752084287526377986730360561230710723922581504781379172731261234878334034473833573601973235946604273704635201327182592410906040097638585857716958419563109577748529579836844756803121874818202833941887076311731615289811756429711334181497218078040465077657204457082859417475114926179367379999220181789399433337731146911970737861041963986422166045588965683206701337505745038872111332436739840284188639147633491695114032583475841514170325690161784931455706904169858050217798497637014758914810543205854914100662201721719726878930012101267481270235940855162601689425111458499658315589660460091525797881670384625905383256920520425791378948827579603278877535466861441826827797651258953563761485994485049706638406266121957141911063246061774180577212381659872472432252969098533628440799030007594546281549235506086481557928961969617060715201589825299772803520002610888814176506636216905928021516429198484077446143617891415191517976537848282687018750030264867608433204658525470555882410254654806040437372771834769014720664234434374255514129178503032471263418076525187802925534774001104853996960549926508093910691337614841834884596365621526610332239417467064368340504749943339802285610313083038484571294767389856293937641914407036507544622061186499127249643799875806537850203753189972618014404667793050140301580709266213229273649718653952866567538572115133606114457222800851183757899219543063413692302293139751143702404830227357629039911794499248480915071002444078482866598579406525539141041497342780203520135419925977628178182825372022920108186449448349255421793982723279357095828748597126780783134286180750497175747373730296280477376908932558914598141724852658299510882230055223242218586191394795184220131553319634363922684259164168669438122537135960710031743651959027712571604588486044820674410935215327906816032054215967959066411120187618531256710150212239401285668608469435937408158536481912528004920724042172170913983123118054043277015835629513656274610248827706488865037765175678806872498861657094846665770674577000207144332525555736557083150320019082992096545498737419756608619533492312940263904930982014700371161829485939931199955070455381196711289367735249958182011774799788636393286405807810818657337668157893827656450642917396685579555053188715314552353070355994740186225988149854660737787698781542360397080977412361518245964026869979609564523828584235953564615185448165799966460648261396618720304839119560250381111550938420209894591555760083897989949964566262540514195610780090298667014635238532066032574466820259430618801773091109212741138269148784355679352572808875543164693077235363768226036080174040660997151176880434927489197133087822951123746632635635328517394189466510943745768270782209928468034684157443127739811044186762032954475468077511126663685479944460934809992951875666499902261686019672053749149951226823637895865245462813439289338365156536992413109638102559114643923805213907862893561660998836479175633176725856523591069520326895990054884753424160586689820067483163174286329119633399132709086065074595260357157323069712106423424081597068328707624437165532750228797802598690981111226558888151520837482450034463046505984569690276166958278982913613535306291331427881888249342136442417833519319786543940201465328083410341785272489879050919932369270996567133507711905899945951923990615156165480300145359212550696405345263823452155999210578191371030188979206408883974767667144727314254467923500524618849237455307575734902707342496298879996942094595961008702501329453325358045689285707241207965919809225550560061971283541270202072583994171175520920820151096509526685113897577150810849443508285458749912943857563115668324566827992991861539009255871716840495663991959154034218364537212023678608655364745175654879318925644085274489190918193411667583563439758886046349413111875241038425467937999203546910411935443113219136068129657568583611774564654674861061988591414805799318725367531243470335482637527081353105570818049642498584646147973467599315946514787025065271083508782350656532331797738656666181652390017664988485456054961300215776115255813396184027067814900350252876823607822107397102339146870159735868589015297010347780503292154014359595298683404657471756232196640515401477953167461726208727304820634652469109953327375561090578378455945469160223687689641425960164689647106348074109928546482353083540132332924864037318003195202317476206537726163717445360549726690601711176761047774971666890152163838974311714180622222345718567941507299526201086205084783127474791909996889937275229053674785020500038630036526218800670926674104806027341997756660029427941090400064654281074454007616429525362460261476180471744322889953285828397762184600967669267581270302806519535452053173536808954589902180783145775891280203970053633193821100095443241244197949192916205234421346395653840781209416214835001155883618421164283992454027590719621537570187067083731012246141362048926555668109467076386536083015847614512581588569610030337081197058344452874666198891534664244887911940711423940115986970795745946337170243268484864632018986352827092313047089215684758207753034387689978702323438584381125011714013265769320554911860153519551654627941175593967947958810333935413289702528893533748106257875620364294270257512121137330213811951395756419122685155962476203282038726342066227347868223036522019655729325905068134849292299647248229359787842720945578267329975853818536442370617353517653060396801087899490506654491544577952166038552398013798104340564182403396162494910454712104839439200945914647542424785991096900046541371091630096785951563947332190934511838669964622788855817353221326876634958059123761251203010983867841195725887799206041260049865895027247133146763722204388398558347770112599424691208308595666787531942465131444389971195968105937957532155524204659410081418351120174196853432672343271868099625045432475688702055341969199545300952644398446384346598830418262932239295612610045884644244285011551557765935780379565026806130721758672048541797157896401554276881090475899564605488362989140226580026134158039480357971019004151547655018391755772677897148793477372747525743898158705040701968215101218826088040084551332795162841280679678965570163917067779841529149397403158167896865448841319046368332179115059107813898261026271979696826411179918656038993895418928488851750122504754778999508544083983800725431468842988412616042682248823097788556495765424017114510393927980290997604904428832198976751320535115230545666467143795931915272680278210241540629795828828466355623580986725638200565215519951793551069127710538552661926903526081367717666435071213453983711357500975854405939558661737828297120544693182260401670308530911657973113259516101749193468250063285777004686987177255226525708428745733039859744230639751837209975339055095883623642814493247460522424051972825153787541962759327436278819283740253185668545040893929401040561666867664402868211607294830305236465560955351079987185041352121321534713770667681396211443891632403235741573773787908838267618458756361026435182951815392455211729022985278518025598478407179607904114472041476091765804302984501746867981277584971731733287305281134969591668387877072315968334322509070204019030503595891994666652037530271923764252552910347950343816357721698115464329245608951158732012675424975710520894362639501382962152214033621065422821876739580121286442788547491928976959315766891987305176388698461503354594898541849550251690616888419122873385522699976822609645007504500096116866129171093180282355042553653997166054753907348915189650027442328981181709248273610863801576007240601649547082331349361582435128299050405405333992577071321011503713898695076713447940748097845416328110406350804863393555238405735580863718763530261867971725608155328716436111474875107033512913923595452951407437943144900950809932872153235195999616750297532475931909938012968640379783553559071355708369947311923538531051736669154087312467233440702525006918026747725078958903448856673081487299464807786497709361969389290891718228134002845552513917355978456150353144603409441211512001738697261466786933733154341007587514908295822756919350542184106448264951943804240543255345965248373785310657979037977505031436474651422484768831323479762673689855474944277949916560108528257618964374464656819789319422077536824661110427671936481836360534108748971066866318805026555929568123959680449295166615409802610781691689418764353363449482900125929366840591370059526914934421861891742142561071896846626335874414976973921566392767687720145153302241853125308442727245771161505550519076276250016522166274796257424425420546785767478190959486500575711016264847833741198041625940813327229905891486422127968042984725356237202887830051788539737909455265135144073130049869453403245984236934627060242579432563660640597549471239092372458126154582526667304702319359866523378856244229188278436440434628094888288712101968642736370461639297485616780079779959696843367730352483047478240669928277140069031660709951473154191919911453182543906294573298686613524886500574780251977607442660798300291573030523199052185718628543687577860915726925232573171665625274275808460620177046433101212443409281314659760221360416223031167750085960128475289259463348312408766740128170543067985261868949895004918275008304998926472034986965363326210919830621495095877228260815566702155693484634079776879525038204442326697479264829899016938511552124688935873289878336267819361764023681714606495185508780596635354698788205094762016350757090024201498400967867845405354130050482404996646978558002628931826518708714613909521454987992300431779500489569529280112698632533646737179519363094399609176354568799002814515169743717518330632232942199132137614506411391269837128970829395360832883050256072727563548374205497856659895469089938558918441085605111510354367477810778500572718180809661542709143010161515013086522842238721618109043183163796046431523184434669799904865336375319295967726080853457652274714047941973192220960296582500937408249714373040087376988068797038047223488825819819025644086847749767508999164153502160223967816357097637814023962825054332801828798160046910336602415904504637333597488119998663995617171089911809851197616486499233594328274275983382931099806461605360243604040848379619072542165869409486682092396143083817303621520642297839982533698027039931804024928814430649614747600087654305571672697259114631990688823893005380061568007730984416061355843701277573463708822073792921409548717956947854414951731561828176343929570234710460088230637509877521391223419548471196982303169544468045517922669260631327498272520906329003279972932906827204647650366969765227673645419031639887433042226322021325368176044169612053532174352764937901877252263626883107879345194133825996368795020985033021472307603375442346871647223795507794130304865403488955400210765171630884759704098331306109510294140865574071074640401937347718815339902047036749084359309086354777210564861918603858715882024476138160390378532660185842568914109194464566162667753712365992832481865739251429498555141512136758288423285957759412684479036912662015308418041737698963759002546999454131659341985624780714434977201991702665380714107259910648709897259362243300706760476097690456341576573395549588448948093604077155688747288451838106069038026528318275560395905381507241627615047252487759578650784894547389096573312763852962664517004459626327934637721151028545472312880039058405918498833810711366073657536918428084655898982349219315205257478363855266205400703561310260405145079325925798227406012199249391735122145336707913500607486561657301854049217477162051678486507913573336334257685988361252720250944019430674728667983441293018131344299088234006652915385763779110955708000600143579956351811596764725075668367726052352939773016348235753572874236648294604770429166438403558846422370760111774821079625901180265548868995181239470625954254584491340203400196442965370643088660925268811549596291166168612036195319253262662271108142149856132646467211954801142455133946382385908540917878668826947602781853283155445565265933912487885639504644196022475186011405239187543742526581685003052301877096152411653980646785444273124462179491306502631062903402737260479940181929954454297256377507172705659271779285537195547433852182309492703218343678206382655341157162788603990157495208065443409462446634653253581574814022471260618973060860559065082163068709634119751925774318683671722139063093061019303182326666420628155129647685313861018672921889347039342072245556791239578260248978371473556820782675452142687314252252601795889759116238720807580527221031327444754083319215135934526961397220564699247718289310588394769170851420631557192703636345039529604362885088555160008371973526383838996789184600327073682083234847108471706160879195227388252347506380811606090840124222431476103563328940609282430125462013806032608121942876847907192546246309055749298781661271916548229644317263587524548607563020667656942355342774617635549231817456159185668061686428714964129290560130053913469569829490891003991259088290348791943368696942620662946948514931472688923571615032405542263391673583102728579723061998175868700492227418629077079508809336215346303842967525604369606110193842723883107587771653594778681499030978765900869583480043137176832954871752604714113064847270887246697164585218774442100900090916189819413456305028950484575822161887397443918833085509908566008543102796375247476265353031558684515120283396640547496946343986288291957510384781539068343717740714095628337554413567955424664601335663617305811711646062717854078898495334329100315985673932305693426085376230981047171826940937686754301837015557540822371538037838383342702379535934403549452173960327095407712107332936507766465603712364707109272580867897181182493799540477008369348889220963814281561595610931815183701135104790176383595168144627670903450457460997444500166918675661035889313483800512736411157304599205955471122443903196476642761038164285918037488354360663299436899730090925177601162043761411616688128178292382311221745850238080733727204908880095181889576314103157447684338100457385008523652069340710078955916549813037292944462306371284357984809871964143085146878525033128989319500645722582281175483887671061073178169281242483613796475692482076321356427357261609825142445262515952514875273805633150964052552659776922077806644338105562443538136258941809788015677378951310313157361136026047890761945591820289365770116416881703644242694283057457471567494391573593353763114830246668754727566653059819746822346578699972291792416156043557665183382167059157867799311835820189855730344883681934418305987021880502259192818047775223884407167894780414701414651073580452021499197980812095692195622632313741870979731320870864552236740416185590793816745658234353037283309503729022429802768451559528656923189798000383061378732434546500582722712325031420712488100290697226311129067629080951145758060270806092801504406139446350643069742785469477459876821004441453438033759717384777232052065301037861326418823586036569054773343070911759152582503029410738914441818378779490613137536794654893375260322906277631983337976816641721083140551864133302224787118511817036598365960493964571491686005656771360533192423185262166760222073368844844409234470948568027905894191829969467724456269443308241243846160408284006424867072583661011433404214473683453638496544701067827313169538435919120440283949541956874453676459875488726170687163109591315801609722382049772577307454562979127906177531663252857205858766376754282917933549923678212008601904369428956102301731743150352204665675088491593025926618816581008701658499456495586855628208747248318351516339189292646558880593601275151838235485893426165223086697314511412035659916934103076974774451947043836739600076578628245472064617380804602903639144493859012422380173377038154675297645596518492676039300171943042511794045679862114630138402371099347243455794730048929825402680821621522346560274258486595687074510352794291633405915025075992398611224340312056999780516223878772230396359709132856830486160362127579561601328561866388146004722200580017580282279272167842720649966956840905752590774886105493806116954293569077377792821084159737469613143291808510446953973485067590503662391722108732333169909603363771705474725026941732982890400239372879549386540463828596742216318201530139629734398479588628632934746650690284066719018081265539973675916799759010867483920062877888531102781695087545740384607594616919584610655963327283485609570305572502494416337066573150237126843581984154103154401008430380631442183776750349813408169325201240813452285974626715177152223063741359255747513535160669108359443999692315898156732033027129284241219651936303734407981204656795322986357374589031654007016472204989445629050395873788912680565516464274460174738175296313458739390484560414203426465560422112239134631023161290836446988901247285192778589195228773637440432659264672239982186452797664826673070168802722052338600372842903155828454593854349099449420750911108532138744823216151007808922516285123275724355101999038195993350032641446053470357293073912578481757987468353429629749652545426864234949270336399427519354240001973125098882419600095766257217621860474573769577649582201796258392376391717855799468922496750179251915218219624653575570564228220399546682648329822996167217080156801080799777126517156274295763666959661983507435667132218383358509536665806605597148376773866922551603463644386269977295750658468929599809168949981898588529537874489519527097766262684177088590284321676352132630838812766335363319004134332844347630067982023716933653652880580156390360562722752187272454764258840995216482554453662083811789117725225682611478014242896970967121967502094421226279437073328703410646312100557376727450271638975234111426287828736758358819056742163061523416789476056879277154789714326222041069587947186435439940738639948986836168919377836648327137363654676901173760246643082285362494712605173293777247276797635865806019396287718060679122426813922872134061694882029506831654589707623668302556167559477498715183426989208952182644710514911419441192277010977616645850068963849426165593473112961064282379048216056210094265076173838082479030510998790719611852832556787472942907151041468948104916751035295897242381802288151276582257190705537652455285511598636421244284176256230139538669970308943645907600684938040875210854159851278070333207779865635907968462191534944587677170063778573171211036517486371634098385626541555573292664616402279791195975248525300376741774056125700303625811704838385391207273191845064713669122576415213769896260940351804147432053600369234179035440735703058314741623452840188940808983125191307741823338981880316339159565954543405777784331681162551898060409183018907512170192983622897099598983405484962284289398469847938668614293324543983592637036699355184231661615244505980576745765335552338715678211466689996845227042954589710922163652573965950289645637766038988037941517917867910675199009966139206238732318786758420544279396366759104126821843375015743069045967947046685602358283919759975285865384338189120042853787549302768972168199113340697282255535300044743958830079799736518459131437946494086272149669719100359399974735262764126125995350902609540048669398955899487421379590802893196914845826873123710180229775301190684280440780938156598081694611679374425663244656799606363751546304833112722231812338371779800439731087402647536582575657351059978314264831879619843765495877803685261751835391844920488198629786329743136948511780579298636452193232481339393090754566368038513630619718033957979522539508697432546502659123585049283028832934489284591373621624852528877442891851104093746333590660233239711922814450735588373324057814862662207486215513375036775585494138678352928273109003823116855374520901095101174796663003330352534143230024288248051396631446632656081582045216883922312025671065388459503224002320453633895521539919011035217362720909565500846486605368975498478995875596103167696587161281951919668893326641203784750417081752273735270989343717167642329956935697166213782736138899530515711822960896394055380431939398453970864418654291655853168697537052760701061488025700785387150835779480952313152747735711713643356413242974208137266896149109564214803567792270566625834289773407718710649866150447478726164249976671481383053947984958938064202886667951943482750168192023591633247099185942520392818083953020434979919361853380201407072481627304313418985942503858404365993281651941497377286729589582881907490040331593436076189609669494800067194371424058105327517721952474344983414191979918179909864631583246021516575531754156198940698289315745851842783390581029411600498699307751428513021286202539508732388779357409781288187000829944831476678183644656510024467827445695591845768068704978044824105799710771577579093525803824227377612436908709875189149049904225568041463131309240101049368241449253427992201346380538342369643767428862595140146178201810734100565466708236854312816339049676558789901487477972479202502227218169405159042170892104287552188658308608452708423928652597536146290037780167001654671681605343292907573031466562485809639550080023347676187068086526878722783177420214068980703410506200235273632267291964034093571225623659496432076928058165514428643204955256838543079254299909353199329432966018220787933122323225928276556048763399988478426451731890365879756498207607478270258861409976050788036706732268192473513646356758611212953074644777149423343867876705824452296605797007134458987594126654609414211447540007211790607458330686866231309155780005966522736183536340439991445294960728379007338249976020630448806064574892740547730693971337007962746135534442514745423654662752252624869916077111131569725392943756732215758704952417232428206555322808868670153681482911738542735797154157943689491063759749151524510096986573825654899585216747260540468342338610760823605782941948009334370046866568258579827323875158302566720152604684361412652956519894291184887986819088277339147282063794512260294515707367105637720023427811802621502691790400488001808901847311751199425460594416773315777951735444490965752131026306836047140331442314298077895617051256930051804287472368435536402764392777908638966566390166776625678575354239947427919442544664643315554138265543388487778859972063679660692327601733858843763144148113561693030468420017434061395220072403658812798249143261731617813894970955038369479594617979829257740992171922783223006387384996138434398468502234780438733784470928703890536420557474836284616809363650973790900204118525835525201575239280826462555785658190226958376345342663420946214426672453987171047721482128157607275305173330963455909323664528978019175132987747952929099598069790148515839540444283988381797511245355548426126784217797728268989735007954505834273726937288386902125284843370917479603207479554080911491866208687184899550445210616155437083299502854903659617362726552868081324793106686855857401668022408227992433394360936223390321499357262507480617409173636062365464458476384647869520547719533384203403990244761056010612777546471464177412625548519830144627405538601855708359981544891286863480720710061787059669365218674805943569985859699554089329219507269337550235821561424994538234781138316591662683103065194730233419384164076823699357668723462219641322516076261161976034708844046473083172682611277723613381938490606534404043904909864126903479263503943531836741051762565704797064478004684323069430241749029731181951132935746854550484711078742905499870600373983113761544808189067620753424526993443755719446665453524088287267537759197074526286322840219629557247932987132852479994638938924943286917770190128914220188747760484939855471168524810559991574441551507431214406120333762869533792439547155394213121021954430556748370425907553004950664994802614794524739012802842646689229455664958621308118913500279654910344806150170407268010067948926855360944990373928383520627992820181576427054962997401900837493444950600754365525758905546552402103412862124809003162941975876195941956592556732874237856112669741771367104424821916671499611728903944393665340294226514575682907490402153401026923964977275904729573320027982816062130523130658731513076913832317193626664465502290735017347656293033318520949298475227462534564256702254695786484819977513326393221579478212493307051107367474918016345667888810782101151826314878755138027101379868751299375133303843885631415175908928986956197561123025310875057188962535763225834275763348421016668109884514141469311719314272028007223449941999003964948245457520704922091620614222912795322688239046498239081592961111003756999529251250673688233852648213896986384052437049402152187547825163347082430303521036927849762517317825860862215614519165573478940019558704784741658847364803865995119651409542615026615147651220820245816010801218275982577477652393859159165067449846149161165153821266726927461290533753163055654440793427876550267301214578324885948736899073512166118397877342715872870912311383472485146035661382188014840560716074652441118841800734067898587159273982452147328317214621907330492060817440914125388918087968538960627860118193099489240811702350413554126823863744341209267781729790694714759018264824761112414556423937732224538665992861551475342773370683344173073150805440138894084087253197595538897613986400165639906934600670780501058567196636796167140097031535132386972899001749862948883362389858632127176571330142071330179992326381982094042993377790345261665892577931395405145369730429462079488033141099249907113241694504241391265397274078984953073730364134893688060340009640631540701820289244667315059736321311926231179142794944897281477264038321021720718017561601025111179022163703476297572233435788863537030535008357679180120653016668316780269873860755423748298548246360981608957670421903145684942967286646362305101773132268579232832164818921732941553151386988781837232271364011755881332524294135348699384658137175857614330952147617551708342432434174779579226338663454959438736807839569911987059388085500837507984051126658973018149321061950769007587519836861526164087252594820126991923916722273718430385263107266000047367872474915828601694439920041571102706081507270147619679971490141639274282889578424398001497985658130305740620028554097382687819891158955487586486645709231721825870342960508203415938806006561845735081804032347750084214100574577342802985404049555529215986404933246481040773076611691605586804857302606467764258503301836174306413323887707999698641372275526317649662882467901094531117120243890323410259937511584651917675138077575448307953064925086002835629697045016137935696266759775923436166369375035368699454550392874449940328328128905560530091416446608691247256021455381248285307613556149618444364923014290938289373215312818797541139219415606631622784836152140668972661027123715779503062132916001988806369127647416567067485490795342762338253943990022498972883660263920518704790601584084302914787302246651371144395418253441269003331181914268070735159284180415100555199146564934872796969351992963117195821262627236458009708099166752820365818699111948365866102758375863322993225541477479210421324166848264953111826527351008031659958888814809945737293785681411438021523876706455063233067233939551964260397443829874822322662036352861302543796600943104500158604854027036789711934695579989189112302233381602302236277726084846296189550730850698061500281436425336666311433321645213882557346329366870956708432252564333895997812402164189946978348320376011613913855499933990786652305860332060641949298931012423081105800169745975038516887112037747631577311831360002742502722451570906304496369230938382329175076469684003556425503797106891999812319602533733677437970687713814747552190142928586781724044248049323750330957002929126630316970587409214456472022710796484778657310660832173093768033821742156446602190335203981531618935787083561603302255162155107179460621892674335641960083663483835896703409115513087820138723494714321400450513941428998350576038799343355677628023346565854351219361896876831439866735726040869511136649881229957801618882834124004126142251475184552502502640896823664946401177803776799157180146386554733265278569418005501363433953502870836220605121839418516239153709790768084909674194289061134979961034672077354959593868862427986411437928435620575955500144308051267664432183688321434583708549082240014585748228606859593502657405750939203135881722442164955416889785558265198046245527898343289578416968890756237467281044803018524217706136533236073856228166664597654076844715963930782091017090763377917711485205493367936868430832404126789220929930411890501756484917499452393770674524578019171841679541825554377930299249277892416277257788147974770446005423669346157135208417428211847353652367573702352791459837645712257646122605628127852169580892808988394594406165340521932514843306105322700231133680378433377389724881307874325614952744243584753011150345103737688223837573804282007358586938044331529253129961025096113761670187568525921208929131354473196308440066835155160913925692912175784379179004808848023029304392630921342768601226558630456913133560978156776098711809238440656353136182676923761613389237802972720736243967239854144480757286813436768000573823963610796223140429490728058551444771338682314499547929338131259971996894072233847404542592316639781608209399269744676323921370773991899853301483814622364299493902073285072098040905300059160091641710175605409814301906444379905831277826625762288108104414704097708248077905168225857235732665234414956169007985520848841886027352780861218049418060017941147110410688703738674378147161236141950474056521041002268987858525470689031657094677131822113205505046579701869337769278257145248837213394613987859786320048011792814546859096532616616068403160077901584946840224344163938313618742275417712170336151163782359059685168880561304838542087505126933144171705880517278127917564053282929427357971823360842784676292324980318169828654166132873909074116734612367109059236155113860447246378721244612580406931724769152219217409096880209008801535633471775664392125733993165330324425899852598966724744126503608416484160724482125980550754851232313331300621490042708542735985913041306918279258584509440150719217604794274047740253314305451367710311947544521321732225875550489799267468541529538871443696399406391099267018219539890685186755868574434469213792094590683677929528246795437302263472495359466300235998990248299853826140395410812427393530207575128774273992824866921285637240069184859771126480352376025469714309316636539718514623865421671429236191647402172547787238964043145364190541101514371773797752463632741619269990461595895793940622986041489302535678633503526382069821487003578061101552210224486633247184367035502326672749787730470216165019711937442505629639916559369593557640005236360445141148916155147776301876302136068825296274460238077523189646894043033182148655637014692476427395401909403584437251915352134557610698046469739424511797999048754951422010043090235713636892619493763602673645872492900162675597083797995647487354531686531900176427222751039446099641439322672532108666047912598938351926694497553568096931962642014042788365702610390456105151611792018698900673027082384103280213487456720062839744828713298223957579105420819286308176631987048287388639069922461848323992902685392499812367091421613488781501234093387999776097433615750910992585468475923085725368613605356762146929424264323906626708602846163376051573599050869800314239735368928435294958099434465414316189806451480849292695749412903363373410480943579407321266012450796613789442208485840536446021616517885568969302685188950832476793300404851688934411125834396590422211152736276278672366665845757559585409486248261694480201791748223085835007862255216359325125768382924978090431102048708975715033330963651576804501966025215527080352103848176167004443740572131294252820989545456276344353575741673638980108310579931697917916718271145837435222026387771805250290791645414791173616253155840768495583288190293564201219633684854080865928095131505012602919562576032932512847250469881908146475324342363863860247943921015193235101390117789997483527186469346024554247028375300033725403910085997650987642832802908445662021678362267272292737780213652404028817217012490974899454430826861772239385250883760749742195942655217301733355851389407457348144161511380845358039740277795072051893487170722955427683655826706766313911972211811528466502223383490906676554168336907959409404576472940901354356409277969379842065738891481990225399022315913388145851487225126560927576795873759207013915029216513720851137197522734365458411622066281660256333632074449918511469174455062297146086578736313585389023662557285424516018080487167823688885575325066254262367702604215835160174851981885460860036597606743233346410471991027562358645341748631726556391320606407754779439671383653877377610828300019937359760370467245737880967939894493795829602910746901609451288456550071458091887879542641820145369659962842686882363495879277007025298960996798975941955735253914237782443302746708282008722602053415292735847582937522487377937899136764642153727843553986244015856488692101644781661602962113570056638347990334049623875941092886778920270077504951511405782565295015024484968204744379710872943108541684540513016310902267112951959140520827546866418137305837933236150599142045255880213558474751516267815309465541240524091663857551298894834797423322854504140527354235070335984964593699534959698554244978249586929179182415068053002553370412778703476446244329205906832901886692400222391918714603175399666877477960121790688623311002908668305431787009355066944389131913333586368037447530664502418437136030852288582121720231274167009740351431532131803978033680228154223490183737494117973254478594157962104378787072154814091725163615415163381388912588517924237727229603497305533840942889918919161186249580560073570527227874940321250645426206304469470804277945973817146810395192821550688079136701210109944220737024613687196031491162370967939354636396448139025711768057799751751298979667073292674886430097398814873780767363792886767781170520534367705731566895899181530825761606591843760505051704242093231358724816618683821026679970982966436224723644898648976857100173643547336955619347638598187756855912376232580849341570570863450733443976604780386678461711520325115528237161469200634713570383377229877321365028868868859434051205798386937002783312365427450532283462669786446920780944052138528653384627970748017872477988461146015077617116261800781557915472305214759943058006652042710117125674185860274188801377931279938153727692612114066810156521441903567333926116697140453812010040811760123270513163743154487571768761575554916236601762880220601068655524141619314312671535587154866747899398685510873576261006923021359580838145290642217792987748784161516349497309700794368305080955621264592795333690631936594413261117944256602433064619312002953123619348034504503004315096798588111896950537335671086336886944665564112662287921812114121425167348136472449021275252555647623248505638391391630760976364990288930588053406631352470996993362568102360392264043588787550723319888417590521211390376609272658409023873553418516426444865247805763826160023858280693148922231457758783791564902227590699346481624734399733206013058796068136378152964615963260698744961105368384203105364183675373594176373955988088591188920114871545460924735613515979992999722298041707112256996310945945097765566409972722824015293663094891067963296735505830412258608050740410916678539569261234499102819759563955711753011823480304181029089719655278245770283085321733741593938595853203645590564229716679900322284081259569032886928291260139267587858284765599075828016611120063145411315144108875767081854894287737618991537664505164279985451077400771946398046265077776614053524831090497899859510873112620613018757108643735744708366215377470972660188656210681516328000908086198554303597948479869789466434027029290899143432223920333487108261968698934611177160561910681226015874410833093070377506876977485840324132474643763087889666151972556180371472590029550718424245405129246729039791532535999005557334600111693557020225722442772950263840538309433999383388018839553821540371447394465152512354603526742382254148328248990134023054550811390236768038649723899924257800315803725555410178461863478690646045865826036072306952576113184134225274786464852363324759102670562466350802553058142201552282050989197818420425028259521880098846231828512448393059455162005455907776121981297954040150653985341579053629101777939776957892084510979265382905626736402636703151957650493344879513766262192237185642999150828898080904189181015450813145034385734032579549707819385285699926238835221520814478940626889936085239827537174490903769904145555260249190126341431327373827075950390882531223536876389814182564965563294518709637484074360669912550026080424160562533591856230955376566866124027875883101021495284600804805028045254063691285010599912421270508133194975917146762267305044225075915290251742774636494555052325186322411388406191257012917881384181566918237215400893603475101448554254698937834239606460813666829750019379115061709452680984785152862123171377897417492087541064556959508967969794980679770961683057941674310519254486327358885118436597143583348756027405400165571178309126113117314169066606067613797690123141099672013123730329707678988740099317309687380126740538923612230370779727025191340850390101739924877352408881040807749924412635346413181858792480760553268122881584307471326768283097203149049868884456187976015468233715478415429742230166504759393312132256510189175368566338139736836336126010908419590215582111816677413843969205870515074254852744810154541079359513596653630049188769523677579147319184225806802539818418929888943038224766186405856591859943091324575886587044653095332668532261321209825839180538360814144791320319699276037194760191286674308615217243049852806380129834255379486287824758850820609389214668693729881191560115633701248675404205911464930888219050248857645752083363921499441937170268576222251074166230901665867067714568862793343153513505688216165112807318529333124070912343832502302341169501745502360505475824093175657701604884577017762183184615567978427541088499501610912720817913532406784267161792013428902861583277304794830971705537485109380418091491750245433432217445924133037928381694330975012918544596923388733288616144238100112755828623259628572648121538348900698511503485369544461542161283241700533583180520082915722904696365553178152398468725451306350506984981006205514844020769539324155096762680887603572463913955278222246439122592651921288446961107463586148252820017348957533954255019475442643148903233373926763409115527189768429887783617346613535388507656327107814312435018965109238453660236940276060642119384227665755210663671879603217527184404651560427289869560206997012906367847161654793068868305846508082886614111979138822898112498261434559408961813509226857611474609406147937240008842153535862052780125014270055274468359151840373309373580494342483940467505708347927948338133276237937844629209323999417593374917899786484958148818865149169302451512835579818112344900827168644548306546633975256079615935830821400021951611342337058359111545217293721664061708131602078213341260356852013161345136871600980378712556766143923146458085652084039744217352744813741215277475202259244561520365608268890193913957991844109971588312780020898275935898106482117936157951837937026741451400902833064466209280549839169261068975151083963132117128513257434964510681479694782619701483204392206140109523453209269311762298139422044308117317394338867965739135764377642819353621467837436136161591167926578700137748127848510041447845416464568496606699139509524527949914769441031612575776863713634644477006787131066832417871556281779122339077841275184193161188155887229676749605752053192594847679397486414128879475647133049543555044790277128690095643357913405127375570391806822344718167939329121448449553897728696601037841520390662890781218240141299368590465146519209198605347788576842696538459445700169758422531241268031418456268722581132040056433413524302102739213788415250475704533878002467378571470021087314693254557923134757243640544448132093266582986850659125571745568328831440322798049274104403921761438405750750288608423536966715191668510428001748971774811216784160854454400190449242294333666338347684438072624307319019363571067447363413698467328522605570126450123348367412135721830146848071241856625742852208909104583727386227300781566668914250733456373259567253354316171586533339843321723688126003809020585719930855573100508771533737446465211874481748868710652311198691114058503492239156755462142467550498676710264926176510110766876596258810039163948397811986615585196216487695936398904500383258041054420595482859955239065758108017936807080830518996468540836412752905182813744878769639548306385089756146421874889271294890398025623046812175145502330254086076115859321603465240763923593699949180470780496764486889980902123735780457040380820770357387588525976042434608851075199334470112741787878845674656640471901619633546770714090590826954225196409446319547658653032104723804625249971910690110456227579220926904132753699634145768795242244563973018311291451151322757841320376225862458224784696669785947914981610522628786944136373683125108310682898766123782697506343047263278453719024447970975017396831214493357290791648779915089163278018852504558488782722376705263811803792477835540018117452957747339714012352011459901984753358434861297092928529424139865507522507808919352104173963493428604871342370429572757862549365917805401652536330410692033704691093097588782938291296447890613200063096560747882082122140978472301680600835812336957051454650181292694364578357815608503303392466039553797630836137289498678842851139853615593352782103740733076818433040893624460576706096188294529171362940967592507631348636606011346115980434147450705511490716640635688739020690279453438236930531133440901381392849163507484449076828386687476663619303412376248380175840467851210698290605196112357188811150723607303158506622574566366740720668999061320627793994112805759798332878792144188725498543014546662945079670707688135022230580562225942983096887732856788971494623888272184647618153045844390967248232348259587963698908456664795754200195991919240707615823002328977439748112690476546256873684352229063217889227643289360535947903046811114130586348244566489159211382258867880972564351646404364328416076247766114349880319792230537889671148058968061594279189647401954989466232962162567264739015818692956765601444248501821713300527995551312539849919933907083138030214072556753022600033565715934283182650908979350869698950542635843046765145668997627989606295925119763672907762567862769469947280606094290314917493590511523235698715397127866718077578671910380368991445381484562682604003456798248689847811138328054940490519768008320299631757043011485087384048591850157264392187414592464617404735275250506783992273121600117160338604710710015235631159734711153198198710616109850375758965576728904060387168114313084172893710817412764581206119054145955378853200366615264923610030157044627231777788649806700723598889528747481372190175074700005571108178930354895017924552067329003818814068686247959272205591627902292600592107710510448103392878991286820705448979977319695574374529708195463942431669050083984398993036790655541596099324867822475424361758944371791403787168166189093900243862038610001362193667280872414291108080291896093127526202667881902085595708111853836166128848729527875143202956393295910508349687029060692838441522579419764824996318479414814660898281725690484184326061946254276693688953540732363428302189694947766126078346328490315128061501009539164530614554234923393806214007779256337619373052025699319099789404390847443596972052065999017828537676265683558625452697455260991024576619614037537859594506363227095122489241931813728141668427013096050734578659047904243852086508154491350136491698639048125666610843702294730266721499164849610746803261583352580352858275799038584091667618877199539888680431991650866887781701439663176815592262016991396613153738021294160006906947533431677802632207226265881842757216055461439677336258462997385077307751473833315101468395296411397329672457933540390136107395245686243008096720460995545708974893048753897955544443791303790422346037768729236001386569593952300768091377768847789746299699489949016141866131552200856673695770822720338936659590666350594330040363762591189195691561626122704788696510356062748423100605472091437069471661080277379848576543481249822444235828329813543645124092220896643987201997945619030397327254617823136363375927622656301565813545578319730419339269008282952718252138855126583037630477490625995514925943105307478901043009876580816508144862607975129633326675259272351611791836777128931053144471668835182920514343609292493191180249366051791485330421043899773019267686085347768149502299280938065840007311767895491286098112311307002535600347898600653805084532572431553654422067661352337408211307834360326940015926958459588297845649462271300855594293344520727007718206398887404742186697709349647758173683580193168322111365547392288184271373843690526638607662451284299368435082612881367358536293873792369928837047900484722240370919885912556341130849457067599032002751632513926694249485692320904596897775676762684224768120033279577059394613185252356456291805905295974791266162882381429824622654141067246487216174351317397697122228010100668178786776119825961537643641828573481088089988571570279722274734750248439022607880448075724807701621064670166965100202654371260046641935546165838945950143502160890185703558173661823437491622669077311800121188299737319891006060966841193266075165452741829459541189277264192546108246351931647783837078295218389645376236304858042774417907169146356546201215125418664885396161542055152375000426794253417764590821513675258479774465114750438460596325820468809667795709044645884673847481638045635188183210386594798204376334738389017759714236223057776395541011294523488098341476645559342209402059733452337956309441446698222457026367119493286653989491344225517746402732596722993581333110831711807234044326813737231209669052411856734897392234152750707954137453460386506786693396236535556479102508529284294227710593056660625152290924148057080971159783458351173168204129645967070633303569271821496292272073250126955216172649821895790908865085382490848904421755530946832055636316431893917626269931034289485184392539670922412565933079102365485294162132200251193795272480340133135247014182195618419055761030190199521647459734401211601239235679307823190770288415814605647291481745105388060109787505925537152356112290181284710137917215124667428500061818271276125025241876177485994084521492727902567005925854431027704636911098800554312457229683836980470864041706010966962231877065395275783874454229129966623016408054769705821417128636329650130416501278156397799631957412627634011130135082721772287129164002237230234809031485343677016544959380750634285293053131127965945266651960426350406454862543383772209428482543536823186182982713182489884498260285705690699045790998144649193654563259496570044689011049923939218088155626191834404362264965506449848521612498442375928443642612004256628602157801140467879662339228190804577624109076487087406157070486658398144845855803277997327929143195789110373530019873110486895656281917362036703039179710646309906285483702836118486672219457621775034511770110458001291255925462680537427727378863726783016568351092332280649908459179620305691566806180826586923920561895421631986004793961133953226395999749526798801074576466538377400437463695133685671362553184054638475191646737948743270916620098057717103475575333102702706317395612448413745782734376330101853438497450236265733191742446567787499665000938706441886733491099877926005340862442833450486907338279348425305698737469497333364267191968992849534561045719338665222471536681145666596959735075972188416698767321649331898967182978657974612216573922404856900225324160367805329990925438960169901664189038843548375648056012628830409421321300206164540821986138099462721214327234457806819925823202851398237118926541234460723597174777907172041523181575194793527456442984630888846385381068621715274531612303165705848974316209831401326306699896632888532682145204083110738032052784669279984003137878996525635126885368435559620598057278951754498694219326972133205286374577983487319388899574634252048213337552584571056619586932031563299451502519194559691231437579991138301656117185508816658756751184338145761060365142858427872190232598107834593970738225147111878311540875777560020664124562293239116606733386480367086953749244898068000217666674827426925968686433731916548717750106343608307376281613984107392410037196754833838054369880310983922140260514297591221159148505938770679068701351029862207502287721123345624421024715163941251258954337788492834236361124473822814504596821452253550035968325337489186278678359443979041598043992124889848660795045011701169092519383155609441705397900600291315024253848282782826223304151370929502192196508374714697845805550615914539506437316401173317807741497557116733034632008408954066541694665746735785483133770133628948904397670025863002540635264006601631712883920305576358989492412827022489373848906764385339931878608019223108328847459816417701264089078551777830131616162049792779670521847212730327970738223860581986744668610994383049960437407323195784473254857416239738852016202384784256163512597161783106850156299135559874758848151014815490937380933394074455700842090155903853444962128368313687375166780513082594599771257467939781491953642874321122421579851584491669362551569370916855252644720786527971466476760328471332985501945689772758983450586004316822658631176606237201721007922216410188299330808409384014213759697185976897042759041500946595252763487628135867117352364964121058854934496645898651826545634382851159137631569519895230262881794959971545221250667461174394884433312659432286710965281109501693028351496524082850120190831078678067061851145740970787563117610746428835593915985421673115153096948758378955979586132649569817205284291038172721213138681565524428109871168862743968021885581515367531218374119972919471325465199144188500672036481975944167950887487934416759598361960010994838744709079104099785974656112459851972157558134628546189728615020774374529539536929655449012953097288963767713353842429715394179547179095580120134210175150931491664699052366350233024087218654727629639065723341455005903913890253699317155917179823065162679744711857951506573868504088229934804445549850597823297898617029498418376255258757455303112991914341109413088238114443068843062655305601658801408561023324210300218460588586954418502977463085858496130037238190325162225570729975710727306066072916922978033647048840958711228045188511908718588299514331534128549297173849768523136276076868494780364948299904475715771141080958058141208956059471668626290036145602625334863284986816039463372436667112964460292915746181117789169695839947080954788863503281129626899231110099889317815313946681882028368363373822281414974006917942192888817139116283910295684918233358930813360131488748366464224381776081007739183393749346933644748150564933649323157235306109385796839902153381449126925350768211098738352197507736653475499431740580563099143218212547336281359488317681489194306530426029773885492974570569448783077945878865062970895499843760181694031056909587141386804846359853684034105948341788438963179956468815791937174656705047441528027712541569401365862097760735632832966564135817028088013546326104892768731829917950379944446328158595181380144716817284996793061814177131912099236282922612543236071226270324572637946863533391758737446552006008819975294017572421299723542069630427857950608911113416534893431149175314953530067419744979017235181671568754163484949491289001739377451431928382431183263265079530371177806185851153508809998200482761808307209649636476943066172549186143700971387567940218696710148540307471561091358933165600167252126542502898612259306484105898847129649230941215144563947889999327145875969555737090855150648002321476443037232466147111552578583071024936898814562568786834745518893385181791667579054210421036349316257870476543126790661216644142285017446278477132740595579600648343288827864837043456066966456899746910373987712891593313271266247505582258634928427718355831641593667712218537642376222104779338956378722902509543014182257180331300148113377736941508488867501893156994849838936052666818012783912005801431596441910546663236810148207799356523056490420711364192200177189107935243234322761787712568251126481332974354926568682748715986654943041648468220593921673359485057849622807932422649812705271398407720995707236227009245067665680069149966555737866411877079767754867028786431817941521796178310655030287157272282250812017060713380339641841211253856248920130010782462165136989511064611133562443838185366273563783436921279354709230119655914915800561707258518503167289370411936374780625824298250726464801821523430268081486978164824349353456855843696378384153838051184406043696871666416514036129729992912630842812149152469877429332305214999981829046119471676727503742221367186614654042534463141660649871499001000660041544868437352208483059495953182872280520828676300361091734508632133033647289584176588755345227938480297724485711815574893561311524926772006362198369980664159549388683836411891430443767715498026544959061738265591178545999378510861446014967645550103653971251138583505085112442517772923814396233043724036032603181442991365750246012787514117944901305803452199992701148071712847770301254994886841867572975189214295652512486943983729047410363121899124217339550688778643130750024823361832738729697376598820053895902935486054979802320400472236873557411858132734337978931582039412878989728973298812553514507641535360519462112217000676321611195841029252568536561813138784086477147099724553013170761712163186600291464501378587854802096244703771373587720086738054108140042311418525803293267396324596914044834665722042880679280616029884043400536534009706581694636096660911110968789751801325224478246957913251892122653056085866541115373584912790254654369020869419871125588453729063224423222287139122012248769976837147645598526739225904997885514250047585260297929306159913444898341973583316070107516452301310796620382579278533125161760789984630103493496981494261055367836366022561213767081421091373531780682420175737470287189310207606953355721704357535177461573524838432101571399813798596607129664438314791296359275429627129436142685922138993054980645399144588692472767598544271527788443836760149912897358259961869729756588978741082189422337344547375227693199222635973520722998387368484349176841191020246627479579564349615012657433845758638834735832242535328142047826934473129971189346354502994681747128179298167439644524956655532311649920677163664580318205849626132234652606175413532444702007661807418914040158148560001030119994109595492321434406067634769713089513389171050503856336503545166431774489640061738861761193622676890576955693918707703942304940038440622614449572516631017080642923345170422426679607075404028551182398361531383751432493056398381877995594942545196756559181968690885283434886050828529642437578712929439366177362830136595872723080969468398938676366226456791132977469812675226595621009318322081754694778878755356188335083870248295346078597023609865656376722755704495258739871812593441903785275571333409842450127258596692434317689018966145404453679047136294238156127656824247864736176671770647002431119711090007474065945650315375044177982192306323700872039212085499569681061379189029961178936752146022386905665481382858280449537530160921422195940638787074787991194920898374091788534417523064715030278397979864517336625329511775105559014160459873338186887977858817291976604516353353556047648420520888811722831990044504284486852338334530105533929637308039738230604714104525470094899407601215247602819963846343554852932377161410869591950786873276075400085220065031871239272857835807010762542769655355964789450166013816295177908531139811092831583216931563867459747449584385282701658246192092219529134323496779345585613140207765996142546463288677356891785576835169608392864188830094883324700447958316931533832382377876344426323456301679513671047510469669001217777128065522453689371871451567394733440447280450959433090683667110655953338602938000999949010642769859623260401863733572846679531229683156358145420890540651226419162015504500430562136991850941034609601030543816694795964585804425194905110733387679946734471718615647723811737035654917628707589456035519195603962301157866323750234725054461073979402475184415558178087962822231972692984516683306919505079993357259165675557294585962182052650473353712351623662770479333289322136141858785972771685682725303734836891911847197133753088446777943274857148827821608844765700041403499921376794209627560883081509438030705666022764678117533361028187800710219794428777313146387857817205661409023041499923248268982477222109852189758140879763486146763606368674611966620347304608917277240045953051376938375381543486981101990651706961774052218247422657652138152740612699012706880875386408669901461740890540981877671880076124151967064152117653084325544261017536348281196837493395825742541244634247233586360777980960199745187758845459645895956779558869098404768259253477849930457883128541747079059795909431627722327844578918694214929451540174214623240300841907975296782445969183509474202123617940309048634960534054931299919496087957952586977170236680033862505764938088740994009589948109397983231108838769236490221499111120870639202892490698435333152727991330986335454324971441378059132240814960156485679843966464780280409057580889190254236606774500413415794312112501275232250148067232979652230488493751166084976116412777395311302041566848265531411348993243747890268935173904043294851610659785832253168204202834993641595980197343889883020994152152288611175126686173051956249367180053845637855129171848417841594797435580617856680758491080185805695567990185198397660693358224779136504562705766735170961550493338390452612404395517449136885115987454340932040102218982707539212403241042424451570052968378815749468441508011138612561164102477190903050040240662278945607061512108266146098662040425010583978098192019726759010749924884966139441184159734610382401178556739080566483321039073867083298691078093495828888707110651559651222542929154212923108071159723275797510859911398076844732639426419452063138217862260999160086752446265457028969067192282283045169111363652774517975842147102219099906257373383472726498678244401048998507631630668050267115944636293525120269424810854530602810627264236538250773340575475701704367039596467715959261029438313074897245505729085688496091346323165819468660587092144653716755655531962091865952628448253731353698162517351930115341581171353292035873164168839107994000677266031617527582917398395852606454113318985505747847121053505795649095931672167565624818782002769963734155880000867852567422461511406015760115910256449002264980039498403358091309140197877843650167960167465370287466062584346329708303725980494653589318912163976013193079476972058034710553111117215859219066231028099212084069283091906017370764654655683413207556315315006453462321007133584907633048328153458698497332599801187479664273140279381289961720524540674695271948079930396730194274036466594154400092799908634806622334906695224044652158992864203435098858422692019340575496840904812955522654754650713532842543496616084954788090727649930252702815067862810825243222979985391759845188868387004477101866772159439708514664612871148749531862180941719676843144666435175837688436786081446319641912566574047718699160915550910878919431253671945651261878486910876729910565595155159739659034383628124629118117760949411880105946336671039049777312004243578115790429823045072038322781246413671297959415082918378213212876890545963586369344879749784841123274921331663162812456388238288715648447883142417650147980187858215768793063001153788998014623690135803753306246148576074932567807682651045738059018831237617271889933790487113395588485234240255002352200613574914318259142479829367775490496399350755839668967578364316618369307625603528602940662803255416535431518013714821941772672244005268401996533334184004345525296592918502940131600651124395297874364222806977720437363717873457948420238745151249157913139411148608416429347958793681868609689684640858334131017858142710955416293375915178392341303110543328703526599993904966822112768158316511246866451167351378214345336650598328347443536290312393672084593164394941881138607974670134709640378534907149089842317891739783650654751982883367395714360000003439863363212091718954899055748693397700245632475954504411422582410783866837655467400137324322809113692670682805397549111166171102397437749479335174036135005397581475520834285772800986189401984375446435081498218360112577632447389452051636938585136484259964518361856989088721789764694721246807900330925083496645841656554261294195108847197209106605105540933731954888406444080280579549008076040034154662137669606444293774985897353625591959618552448187940317374508256072895120945456562159540405425814886929842786582357673195799285293120866275922366115137445767916063621675267440451221051052090834707443986137829082352772895849625656881972792768694795806100573787084121444815034797422312103295359297822377134077549545477791813823542607184617108389097825964406170543546968567030745411634244134486308676327949177682923093183221341455482591367202823284396549001805653203960795517074496039006696990334199278212696767771835209083959545341866777944872740383733381985235884202840150981579594685874537989503257362809837592216229258598599123843993575573285028613155970362934249814178056461615863415338635077223269996508860870999964899373049307170967888740149746147542880387421250689212155876692242387434701120990859082164073576380817386959755176083877600277517253037133445654852635661720197563001580049790223419586738061442401502436288957503206533690825756785507020555105572381878574650371086308158185862815883054564662297694803970618265491385181326737485227188267917919091354407852685476254126683398240534022469989966652573155637645862251862823092085424412805997628505488913098331761884983352975136073772030571342739638126588567405013841074788943393996603591853934198416322617654857376671943132840050626295140357877264680649549355746326408186979718630218760025813995719923601345374229758918285167511358171472625828596940798518571870075823122317068134867930884899275181661399609753105295773584618525865211893339375771859916335112163441037910451845019023066893064178977808158101360449495409665363660370075881004450265734935127707426742578608784898185628869980851665713320835842613381142623855420315774246613108873106318111989880289722849790551075148403702290580483052731884959994156606537314021296702220821915862905952604040620011815269664910068587592655660567562963361434230232810747488395040380984981860056164646099819257616235478710913832967563761506732550860683433720438748186791668975746563456020002562889601191100980453350423842063824039434163502977688802779835087481178298349417211674919425601608685332435385951152061809031241698182079314615062073826097180458265687043623935757495737332781578904386011378078508110273049446611821957450170106059384336519458628360682108585130499820420578458577175933849015564447305834515291412561679970569657426139901681932056241927977282026714297258700193234337873153939403115411184101414292741703537542003698760608765500109345299007034032401334806388514095769557147190364152027721127070187421548123931953220997506553022646844227700020589045922742423904937051507367764629844971682121994198274794049092601715727439368569721862936007387077810797440975556627807371228030350048829843919546433753355787895064018998685060281902452191177018634505171087023903398550540704454189088472042376499749035038518949505897971286631644699407490959473411581934618336692169573605081585080837952036335619947691937965065016808710250735070825260046821242820434367245824478859256555487861614478717581068572356895150707602217433511627331709472765932413249132702425519391509083601346239612335001086614623850633127072987745618984384288764099836164964775714638573247333226653894523588365972955159905187411779288608760239306160016168434070611663449248395156319152882728822831375458678269830696691220130954815935450754923554167766876455212545681242936427474153815692219503331560151614492247512488957534835926226263545406704767033866410025277276800886383266629488582740369655329362236090572479794734434077704284318507901973469071141230364111729224929307731939309795452877412451183953480382210373644697046967493042810911797232448615413264031578430955396671061468083815548947146733652483679138566431084747848676243012018489329109615281108087617422779131629345494425395422727309645057976122885347393189600810965202090151104579377602529543130188938184010247010134929317443562883578609861545691161669857388024973756940558138630581099823372565164920155443216861690537054630176154809626620800633059320775897175589925862195462096455464624399535391743228225433267174308492508396461328929584567927365409119947616225155964704061297047759818551878441419948614013153859322060745185909608884280218943358691959604936409651570327527570641500776261323783648149005245481413195989296398441371781402764122087644989688629798910870164270169014007825748311598976330612951195680427485317886333041169767175063822135213839779138443325644288490872919067009802496281560626258636942322658490628628035057282983101266919109637258378149363774960594515216932644945188292639525772348420077356021656909077097264985642831778694777804964343991762549216500608626285329471055602670413384500507827390640287529864161287496473708235188892189612641279553536442286955430551308700009878557534223100547153412810957024870812654319123261956462149376527526356402127388765103883255007364899937167183280028398832319373301564123277185395654932422977953016534830128490677845037490891749347389015649588574802194996722621185874361039774946338633057887487405540005440439344888192044102134790034598411927024921557026873700970995205391930979319495883265922171508324621942300185974396706491149559411733728199869021311629886680267446443489233020607003821262841723679627307191405008084085703978151998148822390059948911946474438682533745889962375133378280532928272016815977970066488394482446332210928320504045983008943565954267256879714918703447338237767914829203283196838105907715727191903042365315650957464549643425328069510396558733549803850995143463506175361480050195045201350200180281506933241918267855737764414097080945745624854867704904368368717590918057269794010465019484853146726642978667687697789291431128505043098192949736165944259471754765135205245072597538577958372797702972231435199958499522344049394502115428867244188717409524554771867484911475031801773304689909317974472957035192387686405544278134169807249382219749124257510162187439772902147704638010731470653154201300583810458905006764557332998149945854655105526374914354195867992595981412218735238407957416123372264063860431988936249867649693592569592128495906254446474331759999685163660305216426770428154681777589339252115538590526823311608302751194384823861552852465010329467297198112105314125898165100120742688143577590825227466863206188376830450921784582526239594189673003640808624233657620979111641766331328852352062487922978959456450333733139422384778582717195412347860434376165241568717943562570215636666680088531006728947033079540804583324192188488870712275670333173939262509073556164513677064199539111948881240659821685787131385056850623094155206877987539740658484250135205615103489821873770245063583314243624807432542464195984647411575625441010389671576677263196442524931941806472423789334668561083789808830313571333157729435664956078125304917594015895146954965223118559669048559467607968190167266634650186182955669893965019614544401768162810604465068448139561667220729261210164692339016793399632833013163850830967942792934551268435760356901970523138364640961311774904600772840862214747547653221505518116489887879087780918009050706040061220010051271575991225725282523378026809030528461581739558198122397010092017202251606352922464781615533532275453264543087093320924631855976580561717446840450048285353396546862678852330044967795580761661801833668792312510460809773895565488962815089519622093675058841609752282328250433712970186608193748968699961301486924694482420723632912367052542145464162968910442981633373266871675946715392611950649224725627254543274193495995569590243279097174392258098103601486364409101491734183079646345064833303404765711827040276868271418084574998493392039317445402616663674646668754385093967129918067471909885312710726724428584870694307099756567949198418996425748884764622030325637751112534060087936904565779272035205921345924272965206683338510673615276261016026647772485083344719891986802656197236420847504962661607797092906844757798251795569758235084371746103310387911789239441630112634077535773520558040066982523191225570519133631407211349723226549151062961739050617857127509403623146700931176133132018631158730886798239298009805089491510788371194099750375473674305745187265414016446924576792185753680363289139664155342066705623272936001177781498886100830877849571709880858667023104043242526785955562077310543072298032125941107957349146684680220501816192150766649106862033378713826058987655210423668198670177861672671972374156917880001690656659046965316154923604061891820982414006103779407166342002735828911994182647812782659666207030384795881442790246669264032799404016800137293477301530941805070587421153284642203006550763966756168318897005152026656649929417382840327305940740147117478464839241225676523593418554066440983706083636457657081801664285044258224551650808864421212113914352453935225522162483791737330329812349528984098613273709957407786789349311975204237925022851375880436791854547836416773151821457226504640800104202100410766027807729152555503218182387221708112766208665317651926458452495269685376314437998340336947124447247796973890514941120010934140073794061859447165516612674930799374705772930521750426383798367668159183589049652163726492960837147204067428996276720315410211504333742057182854090136325721437592054640471894328548696883599785122262130812989581571391597464534806099601555877223193450760315411663112963843719400333736013305526352571490454327925190794007111504785378036370897340146753465517470747096935814912797188187854376797751675927822300312945518595042883902735494672667647506072643698761394806879080593531793001711000214417701504495496412454361656210150919997862972495905809191825255486358703529320142005857057855419217730505342687533799076038746689684283402648733290888881745453047194740939258407362058242849349024756883352446212456101562729065130618520732925434179252299417447855189995098959999877410951464170076989305620163502192692653166599093238118295411937545448509428621839424186218067457128099385258842631930670182098008050900019819621758458932516877698594110522845465835679362969619219080897536813210484518784516230623911878024604050824909336069998094776253792973597037759066145994638578378211017122446355845171941670344732162722443265914858595797823752976323442911242311368603724514438765801271594060878788638511089680883165505046309006148832545452819908256238805872042843941834687865142541377686054291079721004271658
diff --git a/src/compress/testdata/gettysburg.txt b/src/compress/testdata/gettysburg.txt
new file mode 100644
index 0000000..2c9bcde
--- /dev/null
+++ b/src/compress/testdata/gettysburg.txt
@@ -0,0 +1,29 @@
+ Four score and seven years ago our fathers brought forth on
+this continent, a new nation, conceived in Liberty, and dedicated
+to the proposition that all men are created equal.
+ Now we are engaged in a great Civil War, testing whether that
+nation, or any nation so conceived and so dedicated, can long
+endure.
+ We are met on a great battle-field of that war.
+ We have come to dedicate a portion of that field, as a final
+resting place for those who here gave their lives that that
+nation might live. It is altogether fitting and proper that
+we should do this.
+ But, in a larger sense, we can not dedicate - we can not
+consecrate - we can not hallow - this ground.
+ The brave men, living and dead, who struggled here, have
+consecrated it, far above our poor power to add or detract.
+The world will little note, nor long remember what we say here,
+but it can never forget what they did here.
+ It is for us the living, rather, to be dedicated here to the
+unfinished work which they who fought here have thus far so
+nobly advanced. It is rather for us to be here dedicated to
+the great task remaining before us - that from these honored
+dead we take increased devotion to that cause for which they
+gave the last full measure of devotion -
+ that we here highly resolve that these dead shall not have
+died in vain - that this nation, under God, shall have a new
+birth of freedom - and that government of the people, by the
+people, for the people, shall not perish from this earth.
+
+Abraham Lincoln, November 19, 1863, Gettysburg, Pennsylvania
diff --git a/src/compress/testdata/pi.txt b/src/compress/testdata/pi.txt
new file mode 100644
index 0000000..ca99bbc
--- /dev/null
+++ b/src/compress/testdata/pi.txt
@@ -0,0 +1 @@
+3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472156951623965864573021631598193195167353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617557829735233446042815126272037343146531977774160319906655418763979293344195215413418994854447345673831624993419131814809277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267945612753181340783303362542327839449753824372058353114771199260638133467768796959703098339130771098704085913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931138350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415956258658655705526904965209858033850722426482939728584783163057777560688876446248246857926039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131535958450687724602901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455254079091451357111369410911939325191076020825202618798531887705842972591677813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922334517220138128069650117844087451960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510228334508504860825039302133219715518430635455007668282949304137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282789212507712629463229563989898935821167456270102183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501956730229219139339185680344903982059551002263535361920419947455385938102343955449597783779023742161727111723643435439478221818528624085140066604433258885698670543154706965747458550332323342107301545940516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867446047746491599505497374256269010490377819868359381465741268049256487985561453723478673303904688383436346553794986419270563872931748723320837601123029911367938627089438799362016295154133714248928307220126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605277219005561484255518792530343513984425322341576233610642506390497500865627109535919465897514131034822769306247435363256916078154781811528436679570611086153315044521274739245449454236828860613408414863776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862916421939949072362346468441173940326591840443780513338945257423995082965912285085558215725031071257012668302402929525220118726767562204154205161841634847565169998116141010029960783869092916030288400269104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157959847035622262934860034158722980534989650226291748788202734209222245339856264766914905562842503912757710284027998066365825488926488025456610172967026640765590429099456815065265305371829412703369313785178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291616152881384379099042317473363948045759314931405297634757481193567091101377517210080315590248530906692037671922033229094334676851422144773793937517034436619910403375111735471918550464490263655128162288244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968340800535598491754173818839994469748676265516582765848358845314277568790029095170283529716344562129640435231176006651012412006597558512761785838292041974844236080071930457618932349229279650198751872127267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522742995818072471625916685451333123948049470791191532673430282441860414263639548000448002670496248201792896476697583183271314251702969234889627668440323260927524960357996469256504936818360900323809293459588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885690941130315095261793780029741207665147939425902989695946995565761218656196733786236256125216320862869222103274889218654364802296780705765615144632046927906821207388377814233562823608963208068222468012248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417254370906979396122571429894671543578468788614445812314593571984922528471605049221242470141214780573455105008019086996033027634787081081754501193071412233908663938339529425786905076431006383519834389341596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848308407611830130527932054274628654036036745328651057065874882256981579367897669742205750596834408697350201410206723585020072452256326513410559240190274216248439140359989535394590944070469120914093870012645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678566722796619885782794848855834397518744545512965634434803966420557982936804352202770984294232533022576341807039476994159791594530069752148293366555661567873640053666564165473217043903521329543529169414599041608753201868379370234888689479151071637852902345292440773659495630510074210871426134974595615138498713757047101787957310422969066670214498637464595280824369445789772330048764765241339075920434019634039114732023380715095222010682563427471646024335440051521266932493419673977041595683753555166730273900749729736354964533288869844061196496162773449518273695588220757355176651589855190986665393549481068873206859907540792342402300925900701731960362254756478940647548346647760411463233905651343306844953979070903023460461470961696886885014083470405460742958699138296682468185710318879065287036650832431974404771855678934823089431068287027228097362480939962706074726455399253994428081137369433887294063079261595995462624629707062594845569034711972996409089418059534393251236235508134949004364278527138315912568989295196427287573946914272534366941532361004537304881985517065941217352462589548730167600298865925786628561249665523533829428785425340483083307016537228563559152534784459818313411290019992059813522051173365856407826484942764411376393866924803118364453698589175442647399882284621844900877769776312795722672655562596282542765318300134070922334365779160128093179401718598599933849235495640057099558561134980252499066984233017350358044081168552653117099570899427328709258487894436460050410892266917835258707859512983441729535195378855345737426085902908176515578039059464087350612322611200937310804854852635722825768203416050484662775045003126200800799804925485346941469775164932709504934639382432227188515974054702148289711177792376122578873477188196825462981268685817050740272550263329044976277894423621674119186269439650671515779586756482399391760426017633870454990176143641204692182370764887834196896861181558158736062938603810171215855272668300823834046564758804051380801633638874216371406435495561868964112282140753302655100424104896783528588290243670904887118190909494533144218287661810310073547705498159680772009474696134360928614849417850171807793068108546900094458995279424398139213505586422196483491512639012803832001097738680662877923971801461343244572640097374257007359210031541508936793008169980536520276007277496745840028362405346037263416554259027601834840306811381855105979705664007509426087885735796037324514146786703688098806097164258497595138069309449401515422221943291302173912538355915031003330325111749156969174502714943315155885403922164097229101129035521815762823283182342548326111912800928252561902052630163911477247331485739107775874425387611746578671169414776421441111263583553871361011023267987756410246824032264834641766369806637857681349204530224081972785647198396308781543221166912246415911776732253264335686146186545222681268872684459684424161078540167681420808850280054143613146230821025941737562389942075713627516745731891894562835257044133543758575342698699472547031656613991999682628247270641336222178923903176085428943733935618891651250424404008952719837873864805847268954624388234375178852014395600571048119498842390606136957342315590796703461491434478863604103182350736502778590897578272731305048893989009923913503373250855982655867089242612429473670193907727130706869170926462548423240748550366080136046689511840093668609546325002145852930950000907151058236267293264537382104938724996699339424685516483261134146110680267446637334375340764294026682973865220935701626384648528514903629320199199688285171839536691345222444708045923966028171565515656661113598231122506289058549145097157553900243931535190902107119457300243880176615035270862602537881797519478061013715004489917210022201335013106016391541589578037117792775225978742891917915522417189585361680594741234193398420218745649256443462392531953135103311476394911995072858430658361935369329699289837914941939406085724863968836903265564364216644257607914710869984315733749648835292769328220762947282381537409961545598798259891093717126218283025848112389011968221429457667580718653806506487026133892822994972574530332838963818439447707794022843598834100358385423897354243956475556840952248445541392394100016207693636846776413017819659379971557468541946334893748439129742391433659360410035234377706588867781139498616478747140793263858738624732889645643598774667638479466504074111825658378878454858148962961273998413442726086061872455452360643153710112746809778704464094758280348769758948328241239292960582948619196670918958089833201210318430340128495116203534280144127617285830243559830032042024512072872535581195840149180969253395075778400067465526031446167050827682772223534191102634163157147406123850425845988419907611287258059113935689601431668283176323567325417073420817332230462987992804908514094790368878687894930546955703072619009502076433493359106024545086453628935456862958531315337183868265617862273637169757741830239860065914816164049449650117321313895747062088474802365371031150898427992754426853277974311395143574172219759799359685252285745263796289612691572357986620573408375766873884266405990993505000813375432454635967504844235284874701443545419576258473564216198134073468541117668831186544893776979566517279662326714810338643913751865946730024434500544995399742372328712494834706044063471606325830649829795510109541836235030309453097335834462839476304775645015008507578949548931393944899216125525597701436858943585877526379625597081677643800125436502371412783467926101995585224717220177723700417808419423948725406801556035998390548985723546745642390585850216719031395262944554391316631345308939062046784387785054239390524731362012947691874975191011472315289326772533918146607300089027768963114810902209724520759167297007850580717186381054967973100167870850694207092232908070383263453452038027860990556900134137182368370991949516489600755049341267876436746384902063964019766685592335654639138363185745698147196210841080961884605456039038455343729141446513474940784884423772175154334260306698831768331001133108690421939031080143784334151370924353013677631084913516156422698475074303297167469640666531527035325467112667522460551199581831963763707617991919203579582007595605302346267757943936307463056901080114942714100939136913810725813781357894005599500183542511841721360557275221035268037357265279224173736057511278872181908449006178013889710770822931002797665935838758909395688148560263224393726562472776037890814458837855019702843779362407825052704875816470324581290878395232453237896029841669225489649715606981192186584926770403956481278102179913217416305810554598801300484562997651121241536374515005635070127815926714241342103301566165356024733807843028655257222753049998837015348793008062601809623815161366903341111386538510919367393835229345888322550887064507539473952043968079067086806445096986548801682874343786126453815834280753061845485903798217994599681154419742536344399602902510015888272164745006820704193761584547123183460072629339550548239557137256840232268213012476794522644820910235647752723082081063518899152692889108455571126603965034397896278250016110153235160519655904211844949907789992007329476905868577878720982901352956613978884860509786085957017731298155314951681467176959760994210036183559138777817698458758104466283998806006162298486169353373865787735983361613384133853684211978938900185295691967804554482858483701170967212535338758621582310133103877668272115726949518179589754693992642197915523385766231676275475703546994148929041301863861194391962838870543677743224276809132365449485366768000001065262485473055861598999140170769838548318875014293890899506854530765116803337322265175662207526951791442252808165171667766727930354851542040238174608923283917032754257508676551178593950027933895920576682789677644531840404185540104351348389531201326378369283580827193783126549617459970567450718332065034556644034490453627560011250184335607361222765949278393706478426456763388188075656121689605041611390390639601620221536849410926053876887148379895599991120991646464411918568277004574243434021672276445589330127781586869525069499364610175685060167145354315814801054588605645501332037586454858403240298717093480910556211671546848477803944756979804263180991756422809873998766973237695737015808068229045992123661689025962730430679316531149401764737693873514093361833216142802149763399189835484875625298752423873077559555955465196394401821840998412489826236737714672260616336432964063357281070788758164043814850188411431885988276944901193212968271588841338694346828590066640806314077757725705630729400492940302420498416565479736705485580445865720227637840466823379852827105784319753541795011347273625774080213476826045022851579795797647467022840999561601569108903845824502679265942055503958792298185264800706837650418365620945554346135134152570065974881916341359556719649654032187271602648593049039787489589066127250794828276938953521753621850796297785146188432719223223810158744450528665238022532843891375273845892384422535472653098171578447834215822327020690287232330053862163479885094695472004795231120150432932266282727632177908840087861480221475376578105819702226309717495072127248479478169572961423658595782090830733233560348465318730293026659645013718375428897557971449924654038681799213893469244741985097334626793321072686870768062639919361965044099542167627840914669856925715074315740793805323925239477557441591845821562518192155233709607483329234921034514626437449805596103307994145347784574699992128599999399612281615219314888769388022281083001986016549416542616968586788372609587745676182507275992950893180521872924610867639958916145855058397274209809097817293239301067663868240401113040247007350857828724627134946368531815469690466968693925472519413992914652423857762550047485295476814795467007050347999588867695016124972282040303995463278830695976249361510102436555352230690612949388599015734661023712235478911292547696176005047974928060721268039226911027772261025441492215765045081206771735712027180242968106203776578837166909109418074487814049075517820385653909910477594141321543284406250301802757169650820964273484146957263978842560084531214065935809041271135920041975985136254796160632288736181367373244506079244117639975974619383584574915988097667447093006546342423460634237474666080431701260052055928493695941434081468529815053947178900451835755154125223590590687264878635752541911288877371766374860276606349603536794702692322971868327717393236192007774522126247518698334951510198642698878471719396649769070825217423365662725928440620430214113719922785269984698847702323823840055655517889087661360130477098438611687052310553149162517283732728676007248172987637569816335415074608838663640693470437206688651275688266149730788657015685016918647488541679154596507234287730699853713904300266530783987763850323818215535597323530686043010675760838908627049841888595138091030423595782495143988590113185835840667472370297149785084145853085781339156270760356390763947311455495832266945702494139831634332378975955680856836297253867913275055542524491943589128405045226953812179131914513500993846311774017971512283785460116035955402864405902496466930707769055481028850208085800878115773817191741776017330738554758006056014337743299012728677253043182519757916792969965041460706645712588834697979642931622965520168797300035646304579308840327480771811555330909887025505207680463034608658165394876951960044084820659673794731680864156456505300498816164905788311543454850526600698230931577765003780704661264706021457505793270962047825615247145918965223608396645624105195510522357239739512881816405978591427914816542632892004281609136937773722299983327082082969955737727375667615527113922588055201898876201141680054687365580633471603734291703907986396522961312801782679717289822936070288069087768660593252746378405397691848082041021944719713869256084162451123980620113184541244782050110798760717155683154078865439041210873032402010685341947230476666721749869868547076781205124736792479193150856444775379853799732234456122785843296846647513336573692387201464723679427870042503255589926884349592876124007558756946413705625140011797133166207153715436006876477318675587148783989081074295309410605969443158477539700943988394914432353668539209946879645066533985738887866147629443414010498889931600512076781035886116602029611936396821349607501116498327856353161451684576956871090029997698412632665023477167286573785790857466460772283415403114415294188047825438761770790430001566986776795760909966936075594965152736349811896413043311662774712338817406037317439705406703109676765748695358789670031925866259410510533584384656023391796749267844763708474978333655579007384191473198862713525954625181604342253729962863267496824058060296421146386436864224724887283434170441573482481833301640566959668866769563491416328426414974533349999480002669987588815935073578151958899005395120853510357261373640343675347141048360175464883004078464167452167371904831096767113443494819262681110739948250607394950735031690197318521195526356325843390998224986240670310768318446607291248747540316179699411397387765899868554170318847788675929026070043212666179192235209382278788809886335991160819235355570464634911320859189796132791319756490976000139962344455350143464268604644958624769094347048293294140411146540923988344435159133201077394411184074107684981066347241048239358274019449356651610884631256785297769734684303061462418035852933159734583038455410337010916767763742762102137013548544509263071901147318485749233181672072137279355679528443925481560913728128406333039373562420016045664557414588166052166608738748047243391212955877763906969037078828527753894052460758496231574369171131761347838827194168606625721036851321566478001476752310393578606896111259960281839309548709059073861351914591819510297327875571049729011487171897180046961697770017913919613791417162707018958469214343696762927459109940060084983568425201915593703701011049747339493877885989417433031785348707603221982970579751191440510994235883034546353492349826883624043327267415540301619505680654180939409982020609994140216890900708213307230896621197755306659188141191577836272927461561857103721724710095214236964830864102592887457999322374955191221951903424452307535133806856807354464995127203174487195403976107308060269906258076020292731455252078079914184290638844373499681458273372072663917670201183004648190002413083508846584152148991276106513741539435657211390328574918769094413702090517031487773461652879848235338297260136110984514841823808120540996125274580881099486972216128524897425555516076371675054896173016809613803811914361143992106380050832140987604599309324851025168294467260666138151745712559754953580239983146982203613380828499356705575524712902745397762140493182014658008021566536067765508783804304134310591804606800834591136640834887408005741272586704792258319127415739080914383138456424150940849133918096840251163991936853225557338966953749026620923261318855891580832455571948453875628786128859004106006073746501402627824027346962528217174941582331749239683530136178653673760642166778137739951006589528877427662636841830680190804609849809469763667335662282915132352788806157768278159588669180238940333076441912403412022316368577860357276941541778826435238131905028087018575047046312933353757285386605888904583111450773942935201994321971171642235005644042979892081594307167019857469273848653833436145794634175922573898588001698014757420542995801242958105456510831046297282937584161162532562516572498078492099897990620035936509934721582965174135798491047111660791587436986541222348341887722929446335178653856731962559852026072947674072616767145573649812105677716893484917660771705277187601199908144113058645577910525684304811440261938402322470939249802933550731845890355397133088446174107959162511714864874468611247605428673436709046678468670274091881014249711149657817724279347070216688295610877794405048437528443375108828264771978540006509704033021862556147332117771174413350281608840351781452541964320309576018694649088681545285621346988355444560249556668436602922195124830910605377201980218310103270417838665447181260397190688462370857518080035327047185659499476124248110999288679158969049563947624608424065930948621507690314987020673533848349550836366017848771060809804269247132410009464014373603265645184566792456669551001502298330798496079949882497061723674493612262229617908143114146609412341593593095854079139087208322733549572080757165171876599449856937956238755516175754380917805280294642004472153962807463602113294255916002570735628126387331060058910652457080244749375431841494014821199962764531068006631183823761639663180931444671298615527598201451410275600689297502463040173514891945763607893528555053173314164570504996443890936308438744847839616840518452732884032345202470568516465716477139323775517294795126132398229602394548579754586517458787713318138752959809412174227300352296508089177705068259248822322154938048371454781647213976820963320508305647920482085920475499857320388876391601995240918938945576768749730856955958010659526503036266159750662225084067428898265907510637563569968211510949669744580547288693631020367823250182323708459790111548472087618212477813266330412076216587312970811230758159821248639807212407868878114501655825136178903070860870198975889807456643955157415363193191981070575336633738038272152798849350397480015890519420879711308051233933221903466249917169150948541401871060354603794643379005890957721180804465743962806186717861017156740967662080295766577051291209907944304632892947306159510430902221439371849560634056189342513057268291465783293340524635028929175470872564842600349629611654138230077313327298305001602567240141851520418907011542885799208121984493156999059182011819733500126187728036812481995877070207532406361259313438595542547781961142935163561223496661522614735399674051584998603552953329245752388810136202347624669055816438967863097627365504724348643071218494373485300606387644566272186661701238127715621379746149861328744117714552444708997144522885662942440230184791205478498574521634696448973892062401943518310088283480249249085403077863875165911302873958787098100772718271874529013972836614842142871705531796543076504534324600536361472618180969976933486264077435199928686323835088756683595097265574815431940195576850437248001020413749831872259677387154958399718444907279141965845930083942637020875635398216962055324803212267498911402678528599673405242031091797899905718821949391320753431707980023736590985375520238911643467185582906853711897952626234492483392496342449714656846591248918556629589329909035239233333647435203707701010843880032907598342170185542283861617210417603011645918780539367447472059985023582891833692922337323999480437108419659473162654825748099482509991833006976569367159689364493348864744213500840700660883597235039532340179582557036016936990988671132109798897070517280755855191269930673099250704070245568507786790694766126298082251633136399521170984528092630375922426742575599892892783704744452189363203489415521044597261883800300677617931381399162058062701651024458869247649246891924612125310275731390840470007143561362316992371694848132554200914530410371354532966206392105479824392125172540132314902740585892063217589494345489068463993137570910346332714153162232805522972979538018801628590735729554162788676498274186164218789885741071649069191851162815285486794173638906653885764229158342500673612453849160674137340173572779956341043326883569507814931378007362354180070619180267328551191942676091221035987469241172837493126163395001239599240508454375698507957046222664619000103500490183034153545842833764378111988556318777792537201166718539541835984438305203762819440761594106820716970302285152250573126093046898423433152732131361216582808075212631547730604423774753505952287174402666389148817173086436111389069420279088143119448799417154042103412190847094080254023932942945493878640230512927119097513536000921971105412096683111516328705423028470073120658032626417116165957613272351566662536672718998534199895236884830999302757419916463841427077988708874229277053891227172486322028898425125287217826030500994510824783572905691988555467886079462805371227042466543192145281760741482403827835829719301017888345674167811398954750448339314689630763396657226727043393216745421824557062524797219978668542798977992339579057581890622525473582205236424850783407110144980478726691990186438822932305382318559732869780922253529591017341407334884761005564018242392192695062083183814546983923664613639891012102177095976704908305081854704194664371312299692358895384930136356576186106062228705599423371631021278457446463989738188566746260879482018647487672727222062676465338099801966883680994159075776852639865146253336312450536402610569605513183813174261184420189088853196356986962795036738424313011331753305329802016688817481342988681585577810343231753064784983210629718425184385534427620128234570716988530518326179641178579608888150329602290705614476220915094739035946646916235396809201394578175891088931992112260073928149169481615273842736264298098234063200244024495894456129167049508235812487391799648641133480324757775219708932772262349486015046652681439877051615317026696929704928316285504212898146706195331970269507214378230476875280287354126166391708245925170010714180854800636923259462019002278087409859771921805158532147392653251559035410209284665925299914353791825314545290598415817637058927906909896911164381187809435371521332261443625314490127454772695739393481546916311624928873574718824071503995009446731954316193855485207665738825139639163576723151005556037263394867208207808653734942440115799667507360711159351331959197120948964717553024531364770942094635696982226673775209945168450643623824211853534887989395673187806606107885440005508276570305587448541805778891719207881423351138662929667179643468760077047999537883387870348718021842437342112273940255717690819603092018240188427057046092622564178375265263358324240661253311529423457965569502506810018310900411245379015332966156970522379210325706937051090830789479999004999395322153622748476603613677697978567386584670936679588583788795625946464891376652199588286933801836011932368578558558195556042156250883650203322024513762158204618106705195330653060606501054887167245377942831338871631395596905832083416898476065607118347136218123246227258841990286142087284956879639325464285343075301105285713829643709990356948885285190402956047346131138263878897551788560424998748316382804046848618938189590542039889872650697620201995548412650005394428203930127481638158530396439925470201672759328574366661644110962566337305409219519675148328734808957477775278344221091073111351828046036347198185655572957144747682552857863349342858423118749440003229690697758315903858039353521358860079600342097547392296733310649395601812237812854584317605561733861126734780745850676063048229409653041118306671081893031108871728167519579675347188537229309616143204006381322465841111157758358581135018569047815368938137718472814751998350504781297718599084707621974605887423256995828892535041937958260616211842368768511418316068315867994601652057740529423053601780313357263267054790338401257305912339601880137825421927094767337191987287385248057421248921183470876629667207272325650565129333126059505777727542471241648312832982072361750574673870128209575544305968395555686861188397135522084452852640081252027665557677495969626612604565245684086139238265768583384698499778726706555191854468698469478495734622606294219624557085371272776523098955450193037732166649182578154677292005212667143463209637891852323215018976126034373684067194193037746880999296877582441047878123266253181845960453853543839114496775312864260925211537673258866722604042523491087026958099647595805794663973419064010036361904042033113579336542426303561457009011244800890020801478056603710154122328891465722393145076071670643556827437743965789067972687438473076346451677562103098604092717090951280863090297385044527182892749689212106670081648583395537735919136950153162018908887484210798706899114804669270650940762046502772528650728905328548561433160812693005693785417861096969202538865034577183176686885923681488475276498468821949739729707737187188400414323127636504814531122850990020742409255859252926103021067368154347015252348786351643976235860419194129697690405264832347009911154242601273438022089331096686367898694977994001260164227609260823493041180643829138347354679725399262338791582998486459271734059225620749105308531537182911681637219395188700957788181586850464507699343940987433514431626330317247747486897918209239480833143970840673084079589358108966564775859905563769525232653614424780230826811831037735887089240613031336477371011628214614661679404090518615260360092521947218890918107335871964142144478654899528582343947050079830388538860831035719306002771194558021911942899922722353458707566246926177663178855144350218287026685610665003531050216318206017609217984684936863161293727951873078972637353717150256378733579771808184878458866504335824377004147710414934927438457587107159731559439426412570270965125108115548247939403597681188117282472158250109496096625393395380922195591918188552678062149923172763163218339896938075616855911752998450132067129392404144593862398809381240452191484831646210147389182510109096773869066404158973610476436500068077105656718486281496371118832192445663945814491486165500495676982690308911185687986929470513524816091743243015383684707292898982846022237301452655679898627767968091469798378268764311598832109043715611299766521539635464420869197567370005738764978437686287681792497469438427465256316323005551304174227341646455127812784577772457520386543754282825671412885834544435132562054464241011037955464190581168623059644769587054072141985212106734332410756767575818456990693046047522770167005684543969234041711089888993416350585157887353430815520811772071880379104046983069578685473937656433631979786803671873079693924236321448450354776315670255390065423117920153464977929066241508328858395290542637687668968805033317227800185885069736232403894700471897619347344308437443759925034178807972235859134245813144049847701732361694719765715353197754997162785663119046912609182591249890367654176979903623755286526375733763526969344354400473067198868901968147428767790866979688522501636949856730217523132529265375896415171479559538784278499866456302878831962099830494519874396369070682762657485810439112232618794059941554063270131989895703761105323606298674803779153767511583043208498720920280929752649812569163425000522908872646925284666104665392171482080130502298052637836426959733707053922789153510568883938113249757071331029504430346715989448786847116438328050692507766274500122003526203709466023414648998390252588830148678162196775194583167718762757200505439794412459900771152051546199305098386982542846407255540927403132571632640792934183342147090412542533523248021932277075355546795871638358750181593387174236061551171013123525633485820365146141870049205704372018261733194715700867578539336078622739558185797587258744102542077105475361294047460100094095444959662881486915903899071865980563617137692227290764197755177720104276496949611056220592502420217704269622154958726453989227697660310524980855759471631075870133208861463266412591148633881220284440694169488261529577625325019870359870674380469821942056381255833436421949232275937221289056420943082352544084110864545369404969271494003319782861318186188811118408257865928757426384450059944229568586460481033015388911499486935436030221810943466764000022362550573631294626296096198760564259963946138692330837196265954739234624134597795748524647837980795693198650815977675350553918991151335252298736112779182748542008689539658359421963331502869561192012298889887006079992795411188269023078913107603617634779489432032102773359416908650071932804017163840644987871753756781185321328408216571107549528294974936214608215583205687232185574065161096274874375098092230211609982633033915469494644491004515280925089745074896760324090768983652940657920198315265410658136823791984090645712468948470209357761193139980246813405200394781949866202624008902150166163813538381515037735022966074627952910384068685569070157516624192987244482719429331004854824454580718897633003232525821581280327467962002814762431828622171054352898348208273451680186131719593324711074662228508710666117703465352839577625997744672185715816126411143271794347885990892808486694914139097716736900277758502686646540565950394867841110790116104008572744562938425494167594605487117235946429105850909950214958793112196135908315882620682332156153086833730838173279328196983875087083483880463884784418840031847126974543709373298362402875197920802321878744882872843727378017827008058782410749357514889978911739746129320351081432703251409030487462262942344327571260086642508333187688650756429271605525289544921537651751492196367181049435317858383453865255656640657251363575064353236508936790431702597878177190314867963840828810209461490079715137717099061954969640070867667102330048672631475510537231757114322317411411680622864206388906210192355223546711662137499693269321737043105987225039456574924616978260970253359475020913836673772894438696400028110344026084712899000746807764844088711341352503367877316797709372778682166117865344231732264637847697875144332095340001650692130546476890985050203015044880834261845208730530973189492916425322933612431514306578264070283898409841602950309241897120971601649265613413433422298827909921786042679812457285345801338260995877178113102167340256562744007296834066198480676615805021691833723680399027931606420436812079900316264449146190219458229690992122788553948783538305646864881655562294315673128274390826450611628942803501661336697824051770155219626522725455850738640585299830379180350432876703809252167907571204061237596327685674845079151147313440001832570344920909712435809447900462494313455028900680648704293534037436032625820535790118395649089354345101342969617545249573960621490288728932792520696535386396443225388327522499605986974759882329916263545973324445163755334377492928990581175786355555626937426910947117002165411718219750519831787137106051063795558588905568852887989084750915764639074693619881507814685262133252473837651192990156109189777922008705793396463827490680698769168197492365624226087154176100430608904377976678519661891404144925270480881971498801542057787006521594009289777601330756847966992955433656139847738060394368895887646054983871478968482805384701730871117761159663505039979343869339119789887109156541709133082607647406305711411098839388095481437828474528838368079418884342666222070438722887413947801017721392281911992365405516395893474263953824829609036900288359327745855060801317988407162446563997948275783650195514221551339281978226984278638391679715091262410548725700924070045488485692950448110738087996547481568913935380943474556972128919827177020766613602489581468119133614121258783895577357194986317210844398901423948496659251731388171602663261931065366535041473070804414939169363262373767777095850313255990095762731957308648042467701212327020533742667053142448208168130306397378736642483672539837487690980602182785786216512738563513290148903509883270617258932575363993979055729175160097615459044771692265806315111028038436017374742152476085152099016158582312571590733421736576267142390478279587281505095633092802668458937649649770232973641319060982740633531089792464242134583740901169391964250459128813403498810635400887596820054408364386516617880557608956896727531538081942077332597917278437625661184319891025007491829086475149794003160703845549465385946027452447466812314687943441610993338908992638411847425257044572517459325738989565185716575961481266020310797628254165590506042479114016957900338356574869252800743025623419498286467914476322774005529460903940177536335655471931000175430047504719144899841040015867946179241610016454716551337074073950260442769538553834397550548871099785205401175169747581344926079433689543783221172450687344231989878844128542064742809735625807066983106979935260693392135685881391214807354728463227784908087002467776303605551232386656295178853719673034634701222939581606792509153217489030840886516061119011498443412350124646928028805996134283511884715449771278473361766285062169778717743824362565711779450064477718370221999106695021656757644044997940765037999954845002710665987813603802314126836905783190460792765297277694043613023051787080546511542469395265127101052927070306673024447125973939950514628404767431363739978259184541176413327906460636584152927019030276017339474866960348694976541752429306040727005059039503148522921392575594845078867977925253931765156416197168443524369794447355964260633391055126826061595726217036698506473281266724521989060549880280782881429796336696744124805982192146339565745722102298677599746738126069367069134081559412016115960190237753525556300606247983261249881288192937343476862689219239777833910733106588256813777172328315329082525092733047850724977139448333892552081175608452966590553940965568541706001179857293813998258319293679100391844099286575605993598910002969864460974714718470101531283762631146774209145574041815908800064943237855839308530828305476076799524357391631221886057549673832243195650655460852881201902363644712703748634421727257879503428486312944916318475347531435041392096108796057730987201352484075057637199253650470908582513936863463863368042891767107602111159828875539940120076013947033661793715396306139863655492213741597905119083588290097656647300733879314678913181465109316761575821351424860442292445304113160652700974330088499034675405518640677342603583409608605533747362760935658853109760994238347382222087292464497684560579562516765574088410321731345627735856052358236389532038534024842273371639123973215995440828421666636023296545694703577184873442034227706653837387506169212768015766181095420097708363604361110592409117889540338021426523948929686439808926114635414571535194342850721353453018315875628275733898268898523557799295727645229391567477566676051087887648453493636068278050564622813598885879259940946446041705204470046315137975431737187756039815962647501410906658866162180038266989961965580587208639721176995219466789857011798332440601811575658074284182910615193917630059194314434605154047710570054339000182453117733718955857603607182860506356479979004139761808955363669603162193113250223851791672055180659263518036251214575926238369348222665895576994660491938112486609099798128571823494006615552196112207203092277646200999315244273589488710576623894693889446495093960330454340842102462401048723328750081749179875543879387381439894238011762700837196053094383940063756116458560943129517597713935396074322792489221267045808183313764165818269562105872892447740035947009268662659651422050630078592002488291860839743732353849083964326147000532423540647042089499210250404726781059083644007466380020870126664209457181702946752278540074508552377720890581683918446592829417018288233014971554235235911774818628592967605048203864343108779562892925405638946621948268711042828163893975711757786915430165058602965217459581988878680408110328432739867198621306205559855266036405046282152306154594474489908839081999738747452969810776201487134000122535522246695409315213115337915798026979555710508507473874750758068765376445782524432638046143042889235934852961058269382103498000405248407084403561167817170512813378805705643450616119330424440798260377951198548694559152051960093041271007277849301555038895360338261929343797081874320949914159593396368110627557295278004254863060054523839151068998913578820019411786535682149118528207852130125518518493711503422159542244511900207393539627400208110465530207932867254740543652717595893500716336076321614725815407642053020045340183572338292661915308354095120226329165054426123619197051613839357326693760156914429944943744856809775696303129588719161129294681884936338647392747601226964158848900965717086160598147204467428664208765334799858222090619802173211614230419477754990738738567941189824660913091691772274207233367635032678340586301930193242996397204445179288122854478211953530898910125342975524727635730226281382091807439748671453590778633530160821559911314144205091447293535022230817193663509346865858656314855575862447818620108711889760652969899269328178705576435143382060141077329261063431525337182243385263520217735440715281898137698755157574546939727150488469793619500477720970561793913828989845327426227288647108883270173723258818244658436249580592560338105215606206155713299156084892064340303395262263451454283678698288074251422567451806184149564686111635404971897682154227722479474033571527436819409892050113653400123846714296551867344153741615042563256713430247655125219218035780169240326699541746087592409207004669340396510178134857835694440760470232540755557764728450751826890418293966113310160131119077398632462778219023650660374041606724962490137433217246454097412995570529142438208076098364823465973886691349919784013108015581343979194852830436739012482082444814128095443773898320059864909159505322857914576884962578665885999179867520554558099004556461178755249370124553217170194282884617402736649978475508294228020232901221630102309772151569446427909802190826689868834263071609207914085197695235553488657743425277531197247430873043619511396119080030255878387644206085044730631299277888942729189727169890575925244679660189707482960949190648764693702750773866432391919042254290235318923377293166736086996228032557185308919284403805071030064776847863243191000223929785255372375566213644740096760539439838235764606992465260089090624105904215453927904411529580345334500256244101006359530039598864466169595626351878060688513723462707997327233134693971456285542615467650632465676620279245208581347717608521691340946520307673391841147504140168924121319826881568664561485380287539331160232292555618941042995335640095786495340935115266454024418775949316930560448686420862757201172319526405023099774567647838488973464317215980626787671838005247696884084989185086149003432403476742686245952395890358582135006450998178244636087317754378859677672919526111213859194725451400301180503437875277664402762618941017576872680428176623860680477885242887430259145247073950546525135339459598789619778911041890292943818567205070964606263541732944649576612651953495701860015412623962286413897796733329070567376962156498184506842263690367849555970026079867996261019039331263768556968767029295371162528005543100786408728939225714512481135778627664902425161990277471090335933309304948380597856628844787441469841499067123764789582263294904679812089984857163571087831191848630254501620929805829208334813638405421720056121989353669371336733392464416125223196943471206417375491216357008573694397305979709719726666642267431117762176403068681310351899112271339724036887000996862922546465006385288620393800504778276912835603372548255793912985251506829969107754257647488325341412132800626717094009098223529657957997803018282428490221470748111124018607613415150387569830918652780658896682362523937845272634530420418802508442363190383318384550522367992357752929106925043261446950109861088899914658551881873582528164302520939285258077969737620845637482114433988162710031703151334402309526351929588680690821355853680161000213740851154484912685841268695899174149133820578492800698255195740201818105641297250836070356851055331787840829000041552511865779453963317538532092149720526607831260281961164858098684587525129997404092797683176639914655386108937587952214971731728131517932904431121815871023518740757222100123768721944747209349312324107065080618562372526732540733324875754482967573450019321902199119960797989373383673242576103938985349278777473980508080015544764061053522202325409443567718794565430406735896491017610775948364540823486130254718476485189575836674399791508512858020607820554462991723202028222914886959399729974297471155371858924238493855858595407438104882624648788053304271463011941589896328792678327322456103852197011130466587100500083285177311776489735230926661234588873102883515626446023671996644554727608310118788389151149340939344750073025855814756190881398752357812331342279866503522725367171230756861045004548970360079569827626392344107146584895780241408158405229536937499710665594894459246286619963556350652623405339439142111271810691052290024657423604130093691889255865784668461215679554256605416005071276641766056874274200329577160643448606201239821698271723197826816628249938714995449137302051843669076723577400053932662622760323659751718925901801104290384274185507894887438832703063283279963007200698012244365116394086922220745320244624121155804354542064215121585056896157356414313068883443185280853975927734433655384188340303517822946253702015782157373265523185763554098954033236382319219892171177449469403678296185920803403867575834111518824177439145077366384071880489358256868542011645031357633355509440319236720348651010561049872726472131986543435450409131859513145181276437310438972507004981987052176272494065214619959232142314439776546708351714749367986186552791715824080651063799500184295938799158350171580759883784962257398512129810326379376218322456594236685376799113140108043139732335449090824910499143325843298821033984698141715756010829706583065211347076803680695322971990599904451209087275776225351040902392888779424630483280319132710495478599180196967835321464441189260631526618167443193550817081875477050802654025294109218264858213857526688155584113198560022135158887210365696087515063187533002942118682221893775546027227291290504292259787710667873840000616772154638441292371193521828499824350920891801685572798156421858191197490985730570332667646460728757430565372602768982373259745084479649545648030771598153955827779139373601717422996027353102768719449444917939785144631597314435351850491413941557329382048542123508173912549749819308714396615132942045919380106231421774199184060180347949887691051557905554806953878540066453375981862846419905220452803306263695626490910827627115903856995051246529996062855443838330327638599800792922846659503551211245284087516229060262011857775313747949362055496401073001348853150735487353905602908933526400713274732621960311773433943673385759124508149335736911664541281788171454023054750667136518258284898099512139193995633241336556777098003081910272040997148687418134667006094051021462690280449159646545330107754695413088714165312544813061192407821188690056027781824235022696189344352547633573536485619363254417756613981703930632872166905722259745209192917262199844409646158269456380239502837121686446561785235565164127712826918688615572716201474934052276946595712198314943381622114006936307430444173284786101777743837977037231795255434107223445512555589998646183876764903972461167959018100035098928641204195163551108763204267612979826529425882951141275841262732790798807559751851576841264742209479721843309352972665210015662514552994745127631550917636730259462132930190402837954246323258550301096706922720227074863419005438302650681214142135057154175057508639907673946335146209082888934938376439399256900604067311422093312195936202982972351163259386772241477911629572780752395056251581603133359382311500518626890530658368129988108663263271980611271548858798093487912913707498230575929091862939195014721197586067270092547718025750337730799397134539532646195269996596385654917590458333585799102012713204583903200853878881633637685182083727885131175227769609787962142372162545214591281831798216044111311671406914827170981015457781939202311563871950805024679725792497605772625913328559726371211201905720771409148645074094926718035815157571514050397610963846755569298970383547314100223802583468767350129775413279532060971154506484212185936490997917766874774481882870632315515865032898164228288232746866106592732197907162384642153489852476216789050260998045266483929542357287343977680495774091449538391575565485459058976495198513801007958010783759945775299196700547602252552034453988712538780171960718164078124847847257912407824544361682345239570689514272269750431873633263011103053423335821609333191218806608268341428910415173247216053355849993224548730778822905252324234861531520976938461042582849714963475341837562003014915703279685301868631572488401526639835689563634657435321783493199825542117308467745297085839507616458229630324424328237737450517028560698067889521768198156710781633405266759539424926280756968326107495323390536223090807081455919837355377748742029039018142937311529334644468151212945097596534306284215319445727118614900017650558177095302468875263250119705209476159416768727784472000192789137251841622857783792284439084301181121496366424659033634194540657183544771912446621259392656620306888520055599121235363718226922531781458792593750441448933981608657900876165024635197045828895481793756681046474614105142498870252139936870509372305447734112641354892806841059107716677821238332810262185587751312721179344448201440425745083063944738363793906283008973306241380614589414227694747931665717623182472168350678076487573420491557628217583972975134478990696589532548940335615613167403276472469212505759116251529654568544633498114317670257295661844775487469378464233737238981920662048511894378868224807279352022501796545343757274163910791972952950812942922205347717304184477915673991738418311710362524395716152714669005814700002633010452643547865903290733205468338872078735444762647925297690170912007874183736735087713376977683496344252419949951388315074877537433849458259765560996555954318040920178497184685497370696212088524377013853757681416632722412634423982152941645378000492507262765150789085071265997036708726692764308377229685985169122305037462744310852934305273078865283977335246017463527703205938179125396915621063637625882937571373840754406468964783100704580613446731271591194608435935825987782835266531151065041623295329047772174083559349723758552138048305090009646676088301540612824308740645594431853413755220166305812111033453120745086824339432159043594430312431227471385842030390106070940315235556172767994160020393975099897629335325855575624808996691829864222677502360193257974726742578211119734709402357457222271212526852384295874273501563660093188045493338989741571490544182559738080871565281430102670460284316819230392535297795765862414392701549740879273131051636119137577008929564823323648298263024607975875767745377160102490804624301856524161756655600160859121534556267602192689982855377872583145144082654583484409478463178777374794653580169960779405568701192328608041130904629350871827125934668712766694873899824598527786499569165464029458935064964335809824765965165142090986755203808309203230487342703468288751604071546653834619611223013759451579252696743642531927390036038608236450762698827497618723575476762889950752114804852527950845033958570838130476937881321123674281319487950228066320170022460331989671970649163741175854851878484012054844672588851401562725019821719066960812627785485964818369621410721714214986361918774754509650308957099470934337856981674465828267911940611956037845397855839240761276344105766751024307559814552786167815949657062559755074306521085301597908073343736079432866757890533483669555486803913433720156498834220893399971641479746938696905480089193067138057171505857307148815649920714086758259602876056459782423770242469805328056632787041926768467116266879463486950464507420219373945259262668613552940624781361206202636498199999498405143868285258956342264328707663299304891723400725471764188685351372332667877921738347541480022803392997357936152412755829569276837231234798989446274330454566790062032420516396282588443085438307201495672106460533238537203143242112607424485845094580494081820927639140008540422023556260218564348994145439950410980591817948882628052066441086319001688568155169229486203010738897181007709290590480749092427141018933542818429995988169660993836961644381528877214085268088757488293258735809905670755817017949161906114001908553744882726200936685604475596557476485674008177381703307380305476973609786543859382187220583902344443508867499866506040645874346005331827436296177862518081893144363251205107094690813586440519229512932450078833398788429339342435126343365204385812912834345297308652909783300671261798130316794385535726296998740359570458452230856390098913179475948752126397078375944861139451960286751210561638976008880092746115860800207803341591451797073036835196977766076373785333012024120112046988609209339085365773222392412449051532780950955866459477634482269986074813297302630975028812103517723124465095349653693090018637764094094349837313251321862080214809922685502948454661814715557444709669530177690434272031892770604717784527939160472281534379803539679861424370956683221491465438014593829277393396032754048009552231816667380357183932757077142046723838624617803976292377131209580789363841447929802588065522129262093623930637313496640186619510811583471173312025805866727639992763579078063818813069156366274125431259589936119647626101405563503399523140323113819656236327198961837254845333702062563464223952766943568376761368711962921818754576081617053031590728828700712313666308722754918661395773730546065997437810987649802414011242142773668082751390959313404155826266789510846776118665957660165998178089414985754976284387856100263796543178313634025135814161151902096499133548733131115022700681930135929595971640197196053625033558479980963488718039111612813595968565478868325856437896173159762002419621552896297904819822199462269487137462444729093456470028537694958859591606789282491054412515996300781368367490209374915732896270028656829344431342347351239298259166739503425995868970697267332582735903121288746660451461487850346142827765991608090398652575717263081833494441820193533385071292345774375579344062178711330063106003324053991693682603746176638565758877580201229366353270267100681261825172914608202541892885935244491070138206211553827793565296914576502048643282865557934707209634807372692141186895467322767751335690190153723669036865389161291688887876407525493494249733427181178892759931596719354758988097924525262363659036320070854440784544797348291802082044926670634420437555325050527522833778887040804033531923407685630109347772125639088640413101073817853338316038135280828119040832564401842053746792992622037698718018061122624490909242641985820861751177113789051609140381575003366424156095216328197122335023167422600567941281406217219641842705784328959802882335059828208196666249035857789940333152274817776952843681630088531769694783690580671064828083598046698841098135158654906933319522394363287923990534810987830274500172065433699066117784554364687723631844464768069142828004551074686645392805399409108754939166095731619715033166968309929466349142798780842257220697148875580637480308862995118473187124777291910070227588893486939456289515802965372150409603107761289831263589964893410247036036645058687287589051406841238124247386385427908282733827973326885504935874303160274749063129572349742611221517417153133618622410913869500688835898962349276317316478340077460886655598733382113829928776911495492184192087771606068472874673681886167507221017261103830671787856694812948785048943063086169948798703160515884108282351274153538513365895332948629494495061868514779105804696039069372662670386512905201137810858616188886947957607413585534585151768051973334433495230120395770739623771316030242887200537320998253008977618973129817881944671731160647231476248457551928732782825127182446807824215216469567819294098238926284943760248852279003620219386696482215628093605373178040863727268426696421929946819214908701707533361094791381804063287387593848269535583077395761447997270003472880182785281389503217986345216111066608839314053226944905455527867894417579202440021450780192099804461382547805858048442416404775031536054906591430078158372430123137511562284015838644270890718284816757527123846782459534334449622010096071051370608461801187543120725491334994247617115633321408934609156561550600317384218701570226103101916603887064661438897736318780940711527528174689576401581047016965247557740891644568677717158500583269943401677202156767724068128366565264122982439465133197359199709403275938502669557470231813203243716420586141033606524536939160050644953060161267822648942437397166717661231048975031885732165554988342121802846912529086101485527815277625623750456375769497734336846015607727035509629049392487088406281067943622418704747008368842671022558302403599841645951122485272633632645114017395248086194635840783753556885622317115520947223065437092606797351000565549381224575483728545711797393615756167641692895805257297522338558611388322171107362265816218842443178857488798109026653793426664216990914056536432249301334867988154886628665052346997235574738424830590423677143278792316422403877764330192600192284778313837632536121025336935812624086866699738275977365682227907215832478888642369346396164363308730139814211430306008730666164803678984091335926293402304324974926887831643602681011309570716141912830686577323532639653677390317661361315965553584999398600565155921936759977717933019744688148371103206503693192894521402650915465184309936553493337183425298433679915939417466223900389527673813330617747629574943868716978453767219493506590875711917720875477107189937960894774512654757501871194870738736785890200617373321075693302216320628432065671192096950585761173961632326217708945426214609858410237813215817727602222738133495410481003073275107799948991977963883530734443457532975914263768405442264784216063122769646967156473999043715903323906560726644116438605404838847161912109008701019130726071044114143241976796828547885524779476481802959736049439700479596040292746299203572099761950140348315380947714601056333446998820822120587281510729182971211917876424880354672316916541852256729234429187128163232596965413548589577133208339911288775917226115273379010341362085614577992398778325083550730199818459025958355989260553299673770491722454935329683300002230181517226575787524058832249085821280089747909326100762578770428656006996176212176845478996440705066241710213327486796237430229155358200780141165348065647488230615003392068983794766255036549822805329662862117930628430170492402301985719978948836897183043805182174419147660429752437251683435411217038631379411422095295885798060152938752753799030938871683572095760715221900279379292786303637268765822681241993384808166021603722154710143007377537792699069587121289288019052031601285861825494413353820784883465311632650407642428390870121015194231961652268422003711230464300673442064747718021353070124098860353399152667923871101706221865883573781210935179775604425634694999787251125440854522274810914874307259869602040275941178942581281882159952359658979181144077653354321757595255536158128001163846720319346507296807990793963714961774312119402021297573125165253768017359101557338153772001952444543620071848475663415407442328621060997613243487548847434539665981338717466093020535070271952983943271425371155766600025784423031073429551533945060486222764966687624079324353192992639253731076892135352572321080889819339168668278948281170472624501948409700975760920983724090074717973340788141825195842598096241747610138252643955135259311885045636264188300338539652435997416931322894719878308427600401368074703904097238473945834896186539790594118599310356168436869219485382055780395773881360679549900085123259442529724486666766834641402189915944565309423440650667851948417766779470472041958822043295380326310537494883122180391279678446100139726753892195119117836587662528083690053249004597410947068772912328214304635337283519953648274325833119144459017809607782883583730111857543659958982724531925310588115026307542571493943024453931870179923608166611305426253995833897942971602070338767815033010280120095997252222280801423571094760351925544434929986767817891045559063015953809761875920358937341978962358931125983902598310267193304189215109689156225069659119828323455503059081730735195503721665870288053992138576037035377105178021280129566841984140362872725623214428754302210909472721073474134975514190737043318276626177275996888826027225247133683353452816692779591328861381766349857728936900965749562287103024362590772412219094300871755692625758065709912016659622436080242870024547362036394841255954881727272473653467783647201918303998717627037515724649922289467932322693619177641614618795613956699567783068290316589699430767333508234990790624100202506134057344300695745474682175690441651540636584680463692621274211075399042188716127617787014258864825775223889184599523376292377915585744549477361295525952226578636462118377598473700347971408206994145580719080213590732269233100831759510659019121294795408603640757358750205890208704579670007055262505811420663907459215273309406823649441590891009220296680523325266198911311842016291631076894084723564366808182168657219688268358402785500782804043453710183651096951782335743030504852653738073531074185917705610397395062640355442275156101107261779370634723804990666922161971194259120445084641746383589938239946517395509000859479990136026674261494290066467115067175422177038774507673563742154782905911012619157555870238957001405117822646989944917908301795475876760168094100135837613578591356924455647764464178667115391951357696104864922490083446715486383054477914330097680486878348184672733758436892724310447406807685278625585165092088263813233623148733336714764520450876627614950389949504809560460989604329123358348859990294526400284994280878624039811814884767301216754161106629995553668193123287425702063738352020086863691311733469731741219153633246745325630871347302792174956227014687325867891734558379964351358800959350877556356248810493852999007675135513527792412429277488565888566513247302514710210575352516511814850902750476845518252096331899068527614435138213662152368890578786699432288816028377482035506016029894009119713850179871683633744139275973644017007014763706655703504338121113576415018451821413619823495159601064752712575935185304332875537783057509567425442684712219618709178560783936144511383335649103256405733898667178123972237519316430617013859539474367843392670986712452211189690840236327411496601243483098929941738030588417166613073040067588380432111555379440605497721705942821514886165672771240903387727745629097110134885184374118695655449745736845218066982911045058004299887953899027804383596282409421860556287788428802127553884803728640019441614257499904272009595204654170598104989967504511936471172772220436102614079750809686975176600237187748348016120310234680567112644766123747627852190241202569943534716226660893675219833111813511146503854895025120655772636145473604426859498074396932331297127377157347099713952291182653485155587137336629120242714302503763269501350911612952993785864681307226486008270881333538193703682598867893321238327053297625857382790097826460545598555131836688844628265133798491667839409761353766251798258249663458771950124384040359140849209733754642474488176184070023569580177410177696925077814893386672557898564589851056891960924398841569280696983352240225634570497312245269354193837004843183357196516626721575524193401933099018319309196582920969656247667683659647019595754739345514337413708761517323677204227385674279170698204549953095918872434939524094441678998846319845504852393662972079777452814399418256789457795712552426826089940863317371538896262889629402112108884427376568624527612130371017300785135715404533041507959447776143597437803742436646973247138410492124314138903579092416036406314038149831481905251720937103964026808994832572297954564042701757722904173234796073618787889913318305843069394825961318713816423467218730845133877219086975104942843769325024981656673816260615941768252509993741672883951744066932549653403101452225316189009235376486378482881344209870048096227171226407489571939002918573307460104360729190945767994614929290427981687729426487729952858434647775386906950148984133924540394144680263625402118614317031251117577642829914644533408920976961699098372652361768745605894704968170136974909523072082682887890730190018253425805343421705928713931737993142410852647390948284596418093614138475831136130576108462366837237695913492615824516221552134879244145041756848064120636520170386330129532777699023118648020067556905682295016354931992305914246396217025329747573114094220180199368035026495636955866425906762685687372110339156793839895765565193177883000241613539562437777840801748819373095020699900890899328088397430367736595524891300156633294077907139615464534088791510300651321934486673248275907946807879819425019582622320395131252014109960531260696555404248670549986786923021746989009547850725672978794769888831093487464426400718183160331655511534276155622405474473378049246214952133258527698847336269182649174338987824789278468918828054669982303689939783413747587025805716349413568433929396068192061773331791738208562436433635359863494496890781064019674074436583667071586924521182997893804077137501290858646578905771426833582768978554717687184427726120509266486102051535642840632368481807287940717127966820060727559555904040233178749447346454760628189541512139162918444297651066947969354016866010055196077687335396511614930937570968554559381513789569039251014953265628147011998326992200066392875374713135236421589265126204072887716578358405219646054105435443642166562244565042999010256586927279142752931172082793937751326106052881235373451068372939893580871243869385934389175713376300720319760816604464683937725806909237297523486702916910426369262090199605204121024077648190316014085863558427609537086558164273995349346546314504040199528537252004957805254656251154109252437991326262713609099402902262062836752132305065183934057450112099341464918433323646569371725914489324159006242020612885732926133596808726500045628284557574596592120530341310111827501306961509835515632004310784601906565493806542525229161991819959602752327702249855738824899882707465936355768582560518068964285376850772012220347920993936179268206590142165615925306737944568949070853263568196831861772268249911472615732035807646298116244013316737892788689229032593349861797021994981925739617673075834417098559222170171825712777534491508205278430904619460835217402005838672849709411023266953921445461066215006410674740207009189911951376466904481267253691537162290791385403937560077835153374167747942100384002308951850994548779039346122220865060160500351776264831611153325587705073541279249909859373473787081194253055121436979749914951860535920403830235716352727630874693219622190064260886183676103346002255477477813641012691906569686495012688376296907233961276287223041141813610060264044030035996988919945827397624114613744804059697062576764723766065541618574690527229238228275186799156983390747671146103022776606020061246876477728819096791613354019881402757992174167678799231603963569492851513633647219540611171767387372555728522940054361785176502307544693869307873499110352182532929726044553210797887711449898870911511237250604238753734841257086064069052058452122754533848008205302450456517669518576913200042816758054924811780519832646032445792829730129105318385636821206215531288668564956512613892261367064093953334570526986959692350353094224543865278677673027540402702246384483553239914751363441044050092330361271496081355490531539021002299595756583705381261965683144286057956696622154721695620870013727768536960840704833325132793112232507148630206951245395003735723346807094656483089209801534878705633491092366057554050864111521441481434630437273271045027768661953107858323334857840297160925215326092558932655600672124359464255065996771770388445396181632879614460817789272171836908880126778207430106422524634807454300476492885553409062185153654355474125476152769772667769772777058315801412185688011705028365275543214803488004442979998062157904564161957212784508928489806426497427090579129069217807298769477975112447305991406050629946894280931034216416629935614828130998870745292716048433630818404126469637925843094185442216359084576146078558562473814931427078266215185541603870206876980461747400808324343665382354555109449498431093494759944672673665352517662706772194183191977196378015702169933675083760057163454643671776723387588643405644871566964321041282595645349841388412890420682047007615596916843038999348366793542549210328113363184722592305554383058206941675629992013373175489122037230349072681068534454035993561823576312837767640631013125335212141994611869350833176587852047112364331226765129964171325217513553261867681942338790365468908001827135283584888444111761234101179918709236507184857856221021104009776994453121795022479578069506532965940383987369907240797679040826794007618729547835963492793904576973661643405359792219285870574957481696694062334272619733518136626063735982575552496509807260123668283605928341855848026958413772558970883789942910549800331113884603401939166122186696058491571485733568286149500019097591125218800396419762163559375743718011480559442298730418196808085647265713547612831629200449880315402105530597076666362749328308916880932359290081787411985738317192616728834918402429721290434965526942726402559641463525914348400675867690350382320572934132981593533044446496829441367323442158380761694831219333119819061096142952201536170298575105594326461468505452684975764807808009221335811378197749271768545075538328768874474591593731162470601091244609829424841287520224462594477638749491997840446829257360968534549843266536862844489365704111817793806441616531223600214918768769467398407517176307516849856359201486892943105940202457969622924566644881967576294349535326382171613395757790766370764569570259738800438415805894336137106551859987600754924187211714889295221737721146081154344982665479872580056674724051122007383459271575727715218589946948117940644466399432370044291140747218180224825837736017346685300744985564715420036123593397312914458591522887408719508708632218837288262822884631843717261903305777147651564143822306791847386039147683108141358275755853643597721650028277803713422869688787349795096031108899196143386664068450697420787700280509367203387232629637856038653216432348815557557018469089074647879122436375556668678067610544955017260791142930831285761254481944449473244819093795369008206384631678225064809531810406570254327604385703505922818919878065865412184299217273720955103242251079718077833042609086794273428955735559252723805511440438001239041687716445180226491681641927401106451622431101700056691121733189423400547959684669804298017362570406733282129962153684881404102194463424646220745575643960452985313071409084608499653767803793201899140865814662175319337665970114330608625009829566917638846056762972931464911493704624469351984039534449135141193667933301936617663652555149174982307987072280860859626112660504289296966535652516688885572112276802772743708917389639772257564890533401038855931125679991516589025016486961427207005916056166159702451989051832969278935550303934681219761582183980483960562523091462638447386296039848924386187298507775928792722068554807210497817653286210187476766897248841139560349480376727036316921007350834073865261684507482496448597428134936480372426116704266870831925040997615319076855770327421785010006441984124207396400139603601583810565928413684574119102736420274163723488214524101347716529603128408658419787951116511529827814620379139855006399960326591248525308493690313130100799977191362230866011099929142871249388541612038020411340188887219693477904497527454288072803509305828754420755134816660927879353566521255620139988249628478726214432362853676502591450468377635282587652139156480972141929675549384375582600253168536356731379262475878049445944183429172756988376226261846365452743497662411138451305481449836311789784489732076719508784158618879692955819733250699951402601511675529750575437810242238957925786562128432731202200716730574069286869363930186765958251326499145950260917069347519408975357464016830811798846452473618956056479426358070562563281189269663026479535951097127659136233180866921535788607812759910537171402204506186075374866306350591483916467656723205714516886170790984695932236724946737583099607042589220481550799132752088583781117685214269334786921895240622657921043620348852926267984013953216458791151579050460579710838983371864038024417511347226472547010794793996953554669619726763255229914654933499663234185951450360980344092212206712567698723427940708857070474293173329188523896721971353924492426178641188637790962814486917869468177591717150669111480020759432012061969637795103227089029566085562225452602610460736131368869009281721068198618553780982018471154163630326265699283424155023600978046417108525537612728905335045506135684143775854429677977014660294387687225115363801191758154028120818255606485410787933598921064427244898618961629413418001295130683638609294100083136673372153008352696235737175330738653338204842190308186449184093723944033405244909554558016406460761581010301767488475017661908692946098769201691202181688291040870709560951470416921147027413390052253340834812870353031023919699978597413908593605433599697075604460134242453682496098772581311024732798562072126572499003468293886872304895562253204463602639854225258416464324271611419817802482595563544907219226583863662663750835944314877635156145710745528016159677048442714194435183275698407552677926411261765250615965235457187956673170913319358761628255920783080185206890151504713340386100310055914817852110384754542933389188444120517943969970194112695119526564919594189975418393234647424290702718875223534393673633663200307232747037407123982562024662651974090199762452056198557625760008708173083288344381831070054514493545885422678578551915372292379555494333410174420169600090696415612732297770221217951868376359082255128816470021992348864043959153018464004714321186360622527011541122283802778538911098490201342741014121559769965438877197485376431158229838533123071751132961904559007938064276695819014842627991221792947987348901868471676503827328552059082984529806259250352128451925927986593506132961946796252373972565584157853744567558998032405492186962888490332560851455344391660226257775512916200772796852629387937530454181080729285891989715381797343496187232927614747850192611450413274873242970583408471112333746274617274626582415324271059322506255302314738759251724787322881491455915605036334575424233779160374952502493022351481961381162563911415610326844958072508273431765944054098269765269344579863479709743124498271933113863873159636361218623497261409556079920628316999420072054811525353393946076850019909886553861433495781650089961649079678142901148387645682174914075623767618453775144031475411206760160726460556859257799322070337333398916369504346690694828436629980037414527627716547623825546170883189810868806847853705536480469350958818025360529740793538676511195079373282083146268960071075175520614433784114549950136432446328193346389050936545714506900864483440180428363390513578157273973334537284263372174065775771079830517555721036795976901889958494130195999573017901240193908681356585539661941371794487632079868800371607303220547423572266896801882123424391885984168972277652194032493227314793669234004848976059037958094696041754279613782553781223947646147832926976545162290281701100437846038756544151739433960048915318817576650500951697402415644771293656614253949368884230517400129920556854289853897942669956777027089146513736892206104415481662156804219838476730871787590279209175900695273456682026513373111518000181434120962601658629821076663523361774007837783423709152644063054071807843358061072961105550020415131696373046849213356837265400307509829089364612047891114753037049893952833457824082817386441322710002968311940203323456420826473276233830294639378998375836554559919340866235090967961134004867027123176526663710778725111860354037554487418693519733656621772359229396776463251562023487570113795712096237723431370212031004965152111976013176419408203437348512852602913334915125083119802850177855710725373149139215709105130965059885999931560863655477403551898166733535880048214665099741433761182777723351910741217572841592580872591315074606025634903777263373914461377038021318347447301113032670296917335047701632106616227830027269283365584011791419447808748253360714403296252285775009808599609040936312635621328162071453406104224112083010008587264252112262480142647519426184325853386753874054743491072710049754281159466017136122590440158991600229827801796035194080046513534752698777609527839984368086908989197839693532179980139135442552717910225397010810632143048511378291498511381969143043497500189980681644412123273328307192824362406733196554692677851193152775113446468905504248113361434984604849051258345683266441528489713972376040328212660253516693914082049947320486021627759791771234751097502403078935759937715095021751693555827072533911892334070223832077585802137174778378778391015234132098489423459613692340497998279304144463162707214796117456975719681239291913740982925805561955207434243295982898980529233366415419256367380689494201471241340525072204061794355252555225008748790086568314542835167750542294803274783044056438581591952666758282929705226127628711040134801787224801789684052407924360582742467443076721645270313451354167649668901274786801010295133862698649748212118629040337691568576240699296372493097201628707200189835423690364149270236961938547372480329855045112089192879829874467864129159417531675602533435310626745254507114181483239880607297140234725520713490798398982355268723950909365667878992383712578976248755990443228895388377317348941122757071410959790047919301046740750411435381782464630795989555638991884773781341347070246747362112048986226991888517456251732519341352038115863350123913054441910073628447567514161050410973505852762044489190978901984315485280533985777844313933883994310444465669244550885946314081751220331390681596592510546858013133838152176418210433429788826119630443111388796258746090226130900849975430395771243230616906262919403921439740270894777663702488155499322458825979020631257436910946393252806241642476868495455324938017639371615636847859823715902385421265840615367228607131702674740131145261063765383390315921943469817605358380310612887852051546933639241088467632009567089718367490578163085158138161966882222047570437590614338040725853862083565176998426774523195824182683698270160237414938363496629351576854061397342746470899685618170160551104880971554859118617189668025973541705423985135560018720335079060946421271143993196046527424050882225359773481519135438571253258540493946010865793798058620143366078825219717809025817370870916460452727977153509910340736425020386386718220522879694458387652947951048660717390229327455426785669776865939923416834122274663015062155320502655341460995249356050854921756549134830958906536175693817637473644183378974229700703545206663170929607591989627732423090252397443861014263098687733913882518684316501027964911497737582888913450341148865948670215492101084328080783428089417298008983297536940644969903125399863919581601468995220880662285408414864274786281975546629278814621607171381880180840572084715868906836919393381864278454537956719272397972364651667592011057995663962598535512763558768140213409829016296873429850792471846056874828331381259161962476156902875901072733103299140623864608333378638257926302391590003557609032477281338887339178096966601469615031754226751125993315529674213336300222964906480934582008181061802100227664580400278213336758573019011371754672763059044353131319036092489097246427928455549913490005180295707082919052556781889913899625138662319380053611346224294610248954072404857123256628888931722116432947816190554868054943441034090680716088028227959686950133643814268252170472870863010137301155236861416908375675747637239763185757038109443390564564468524183028148107998376918512127201935044041804604721626939445788377090105974693219720558114078775989772072009689382249303236830515862657281114637996983137517937623215111252349734305240622105244234353732905655163406669506165892878218707756794176080712973781335187117931650033155523822487730653444179453415395202424449703410120874072188109388268167512042299404948179449472732894770111574139441228455521828424922240658752689172272780607116754046973008037039618787796694882555614674384392570115829546661358678671897661297311267200072971553613027503556167817765442287442114729881614802705243806817653573275578602505847084013208837932816008769081300492491473682517035382219619039014999523495387105997351143478292339499187936608692301375596368532373806703591144243268561512109404259582639301678017128669239283231057658851714020211196957064799814031505633045141564414623163763809904402816256917576489142569714163598439317433270237812336938043012892626375382667795034169334323607500248175741808750388475094939454896209740485442635637164995949920980884294790363666297526003243856352945844728944547166209297495496616877414120882130477022816116456044007236351581149729739218966737382647204722642221242016560150284971306332795814302516013694825567014780935790889657134926158161346901806965089556310121218491805847922720691871696316330044858020102860657858591269974637661741463934159569539554203314628026518951167938074573315759846086173702687867602943677780500244673391332431669880354073232388281847501051641331189537036488422690270478052742490603492082954755054003457160184072574536938145531175354210726557835615499874447480427323457880061873149341566046352979779455075359304795687209316724536547208381685855606043801977030764246083489876101345709394877002946175792061952549255757109038525171488525265671045349813419803390641529876343695420256080277614421914318921393908834543131769685101840103844472348948869520981943531906506555354617335814045544837884752526253949665869992058417652780125341033896469818642430034146791380619028059607854888010789705516946215228773090104467462497979992627120951684779568482583341402266477210843362437593741610536734041954738964197895425335036301861400951534766961476255651873823292468547356935802896011536791787303553159378363082248615177770541577576561759358512016692943111138863582159667618830326104164651714846979385422621687161400122378213779774131268977266712992025922017408770076956283473932201088159356286281928563571893384958850603853158179760679479840878360975960149733420572704603521790605647603285569276273495182203236144112584182426247712012035776388895974318232827871314608053533574494297621796789034568169889553518504478325616380709476951699086247100019748809205009521943632378719764870339223811540363475488626845956159755193765410115014067001226927474393888589943859730245414801061235908036274585288493563251585384383242493252666087588908318700709100237377106576985056433928854337658342596750653715005333514489908293887737352051459333049626531415141386124437935885070944688045486975358170212908490787347806814366323322819415827345671356443171537967818058195852464840084032909981943781718177302317003989733050495387356116261023999433259780126893432605584710278764901070923443884634011735556865903585244919370181041626208504299258697435817098133894045934471937493877624232409852832762266604942385129709453245586252103600829286649724174919141988966129558076770979594795306013119159011773943104209049079424448868513086844493705909026006120649425744710353547657859242708130410618546219881830090634588187038755856274911587375421064667951346487586771543838018521348281915812462599335160198935595167968932852205824799421034512715877163345222995418839680448835529753361286837225935390079201666941339091168758803988828869216002373257361588207163516271332810518187602104852180675526648673908900907195138058626735124312215691637902277328705410842037841525683288718046987952513073266340278519059417338920358540395677035611329354482585628287610610698229721420961993509331312171187891078766872044548876089410174798647137882462153955933333275562009439580434537919782280590395959927436913793778664940964048777841748336432684026282932406260081908081804390914556351936856063045089142289645219987798849347477729132797266027658401667890136490508741142126861969862044126965282981087045479861559545338021201155646979976785738920186243599326777689454060508218838227909833627167124490026761178498264377033002081844590009717235204331994708242098771514449751017055643029542821819670009202515615844174205933658148134902693111517093872260026458630561325605792560927332265579346280805683443921373688405650434307396574061017779370141424615493070741360805442100295600095663588977899267630517718781943706761498217564186590116160865408635391513039201316805769034172596453692350806417446562351523929050409479953184074862151210561833854566176652606393713658802521666223576132201941701372664966073252010771947931265282763302413805164907174565964853748354669194523580315301969160480994606814904037819829732360930087135760798621425422096419004367905479049930078372421581954535418371129368658430553842717628035279128821129308351575656599944741788438381565148434229858704245592434693295232821803508333726283791830216591836181554217157448465778420134329982594566884558266171979012180849480332448787258183774805522268151011371745368417870280274452442905474518234674919564188551244421337783521423865979925988203287085109338386829906571994614906290257427686038850511032638544540419184958866538545040571323629681069146814847869659166861842756798460041868762298055562963045953227923051616721591968675849523635298935788507746081537321454642984792310511676357749494622952569497660359473962430995343310404994209677883827002714478494069037073249106444151696053256560586778757417472110827435774315194060757983563629143326397812218946287447798119807225646714664054850131009656786314880090303749338875364183165134982546694673316118123364854397649325026179549357204305402182974871251107404011611405899911093062492312813116340549262571356721818628932786138833718028535056503591952741400869510926167541476792668032109237467087213606278332922386413619594121339278036118276324106004740971111048140003623342714514483334641675466354699731494756643423659493496845884551524150756376605086632827424794136062876041290644913828519456402643153225858624043141838669590633245063000392213192647625962691510904457695301444054618037857503036686212462278639752746667870121003392984873375014475600322100622358029343774955032037012738468163061026570300872275462966796880890587127676361066225722352229739206443093524327228100859973095132528630601105497915644791845004618046762408928925680912930592960642357021061524646205023248966593987324933967376952023991760898474571843531936646529125848064480196520162838795189499336759241485626136995945307287254532463291529110128763770605570609531377527751867923292134955245133089867969165129073841302167573238637575820080363575728002754490327953079900799442541108725693188014667935595834676432868876966610097395749967836593397846346959948950610490383647409504695226063858046758073069912290474089879166872117147527644711604401952718169508289733537148530928937046384420893299771125856840846608339934045689026787516008775461267988015465856522061210953490796707365539702576199431376639960606061106406959330828171876426043573425361756943784848495250108266488395159700490598380812105221111091943323951136051446459834210799058082093716464523127704023160072138543723461267260997870385657091998507595634613248460188409850194287687902268734556500519121546544063829253851276317663922050938345204300773017029940362615434001322763910912988327863920412300445551684054889809080779174636092439334912641164240093880746356607262336695842764583698268734815881961058571835767462009650526065929263548291499045768307210893245857073701660717398194485028842603963660746031184786225831056580870870305567595861341700745402965687634774176431051751036732869245558582082372038601781739405175130437994868822320044378043103170921034261674998000073016094814586374488778522273076330495383944345382770608760763542098445008306247630253572781032783461766970544287155315340016497076657195985041748199087201490875686037783591994719343352772947285537925787684832301101859365800717291186967617655053775030293033830706448912811412025506150896411007623824574488655182581058140345320124754723269087547507078577659732542844459353044992070014538748948226556442223696365544194225441338212225477497535494624827680533336983284156138692363443358553868471111430498248398991803165458638289353799130535222833430137953372954016257623228081138499491876144141322933767106563492528814528239506209022357876684650116660097382753660405446941653422239052108314585847035529352219928272760574821266065291385530345549744551470344939486863429459658431024190785923680224560763936784166270518555178702904073557304620639692453307795782245949710420188043000183881429008173039450507342787013124466860092778581811040911511729374873627887874907465285565434748886831064110051023020875107768918781525622735251550379532444857787277617001964853703555167655209119339343762866284619844026295252183678522367475108809781507098978413086245881522660963551401874495836926917799047120726494905737264286005211403581231076006699518536124862746756375896225299116496066876508261734178484789337295056739007878617925351440621045366250640463728815698232317500596261080921955211150859302955654967538862612972339914628358476048627627027309739202001432248707582337354915246085608210328882974183906478869923273691360048837436615223517058437705545210815513361262142911815615301758882573594892507108879262128641392443309383797333867806131795237315266773820858024701433527009243803266951742119507670884326346442749127558907746863582162166042741315170212458586056233631493164646913946562497471741958354218607748711057338458433689939645913740603382159352243594751626239188685307822821763983237306180204246560477527943104796189724299533029792497481684052893791044947004590864991872727345413508101983881864673609392571930511968645601855782450218231065889437986522432050677379966196955472440585922417953006820451795370043472451762893566770508490213107736625751697335527462302943031203596260953423574397249659211010657817826108745318874803187430823573699195156340957162700992444929749105489851519658664740148225106335367949737142510229341882585117371994499115097583746130105505064197721531929354875371191630262030328588658528480193509225875775597425276584011721342323648084027143356367542046375182552524944329657043861387865901965738802868401894087672816714137033661732650120578653915780703088714261519075001492576112927675193096728453971160213606303090542243966320674323582797889332324405779199278484633339777737655901870574806828678347965624146102899508487399692970750432753029972872297327934442988646412725348160603779707298299173029296308695801996312413304939350493325412355071054461182591141116454534710329881047844067780138077131465400099386306481266614330858206811395838319169545558259426895769841428893743467084107946318932539106963955780706021245974898293564613560788983472419979478564362042094613412387613198865352358312996862268948608408456655606876954501274486631405054735351746873009806322780468912246821460806727627708402402266155485024008952891657117617439020337584877842911289623247059191874691042005848326140677333751027195653994697162517248312230633919328707983800748485726516123434933273356664473358556430235280883924348278760886164943289399166399210488307847777048045728491456303353265070029588906265915498509407972767567129795010098229476228961891591441520032283878773485130979081019129267227103778898053964156362364169154985768408398468861684375407065121039062506128107663799047908879674778069738473170475253442156390387201238806323688037017949308954900776331523063548374256816653361606641980030188287123767481898330246836371488309259283375902278942588060087286038859168849730693948020511221766359138251524278670094406942355120201568377778851824670025651708509249623747726813694284350062938814429987905301056217375459182679973217735029368928065210025396268807498092643458011655715886700443503976505323478287327368840863540002740676783821963522226539290939807367391364082898722017776747168118195856133721583119054682936083236976113450281757830202934845982925000895682630271263295866292147653142233351793093387951357095346377183684092444422096319331295620305575517340067973740614162107923633423805646850092037167152642556371853889571416419772387422610596667396997173168169415435095283193556417705668622215217991151355639707143312893657553844648326201206424338016955862698561022460646069330793847858814367407000599769703649019273328826135329363112403650698652160638987250267238087403396744397830258296894256896741864336134979475245526291426522842419243083388103580053787023999542172113686550275341362211693140694669513186928102574795985605145005021715913317751609957865551981886193211282110709442287240442481153406055895958355815232012184605820563592699303478851132068626627588771446035996656108430725696500563064489187599466596772847171539573612108180841547273142661748933134174632662354222072600146012701206934639520564445543291662986660783089068118790090815295063626782075614388815781351134695366303878412092346942868730839320432333872775496805210302821544324723388845215343727250128589747691460808314404125868181540049187772287869801853454537006526655649170915429522756709222217474112062720656622989806032891672068743654948246108697367225547404812889242471854323605753411672850757552057131156697954584887398742228135887985840783135060548290551482785294891121905383195624228719484759407859398047901094194070671764439032730712135887385049993638838205501683402777496070276844880281912220636888636811043569529300652195528261526991271637277388418993287130563464688227398288763198645709836308917786487086676185485680047672552675414742851028145807403152992197814557756843681110185317498167016426647884090262682824448258027532094549915104518517716546311804904567985713257528117913656278158111288816562285876030875974963849435275676612168959261485030785362045274507752950631012480341804584059432926079854435620093708091821523920371790678121992280496069738238743312626730306795943960954957189577217915597300588693646845576676092450906088202212235719254536715191834872587423919410890444115959932760044506556206461164655665487594247369252336955993030355095817626176231849561906494839673002037763874369343999829430209147073618947932692762445186560239559053705128978163455423320114975994896278424327483788032701418676952621180975006405149755889650293004867605208010491537885413909424531691719987628941277221129464568294860281493181560249677887949813777216229359437811004448060797672429276249510784153446429150842764520002042769470698041775832209097020291657347251582904630910359037842977572651720877244740952267166306005469716387943171196873484688738186656751279298575016363411314627530499019135646823804329970695770150789337728658035712790913767420805655493624646
diff --git a/src/compress/zlib/example_test.go b/src/compress/zlib/example_test.go
new file mode 100644
index 0000000..7040889
--- /dev/null
+++ b/src/compress/zlib/example_test.go
@@ -0,0 +1,37 @@
+// Copyright 2012 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 zlib_test
+
+import (
+ "bytes"
+ "compress/zlib"
+ "fmt"
+ "io"
+ "os"
+)
+
+func ExampleNewWriter() {
+ var b bytes.Buffer
+
+ w := zlib.NewWriter(&b)
+ w.Write([]byte("hello, world\n"))
+ w.Close()
+ fmt.Println(b.Bytes())
+ // Output: [120 156 202 72 205 201 201 215 81 40 207 47 202 73 225 2 4 0 0 255 255 33 231 4 147]
+}
+
+func ExampleNewReader() {
+ buff := []byte{120, 156, 202, 72, 205, 201, 201, 215, 81, 40, 207,
+ 47, 202, 73, 225, 2, 4, 0, 0, 255, 255, 33, 231, 4, 147}
+ b := bytes.NewReader(buff)
+
+ r, err := zlib.NewReader(b)
+ if err != nil {
+ panic(err)
+ }
+ io.Copy(os.Stdout, r)
+ // Output: hello, world
+ r.Close()
+}
diff --git a/src/compress/zlib/reader.go b/src/compress/zlib/reader.go
new file mode 100644
index 0000000..10954ea
--- /dev/null
+++ b/src/compress/zlib/reader.go
@@ -0,0 +1,181 @@
+// Copyright 2009 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 zlib implements reading and writing of zlib format compressed data,
+as specified in RFC 1950.
+
+The implementation provides filters that uncompress during reading
+and compress during writing. For example, to write compressed data
+to a buffer:
+
+ var b bytes.Buffer
+ w := zlib.NewWriter(&b)
+ w.Write([]byte("hello, world\n"))
+ w.Close()
+
+and to read that data back:
+
+ r, err := zlib.NewReader(&b)
+ io.Copy(os.Stdout, r)
+ r.Close()
+*/
+package zlib
+
+import (
+ "bufio"
+ "compress/flate"
+ "encoding/binary"
+ "errors"
+ "hash"
+ "hash/adler32"
+ "io"
+)
+
+const (
+ zlibDeflate = 8
+ zlibMaxWindow = 7
+)
+
+var (
+ // ErrChecksum is returned when reading ZLIB data that has an invalid checksum.
+ ErrChecksum = errors.New("zlib: invalid checksum")
+ // ErrDictionary is returned when reading ZLIB data that has an invalid dictionary.
+ ErrDictionary = errors.New("zlib: invalid dictionary")
+ // ErrHeader is returned when reading ZLIB data that has an invalid header.
+ ErrHeader = errors.New("zlib: invalid header")
+)
+
+type reader struct {
+ r flate.Reader
+ decompressor io.ReadCloser
+ digest hash.Hash32
+ err error
+ scratch [4]byte
+}
+
+// Resetter resets a ReadCloser returned by NewReader or NewReaderDict
+// to switch to a new underlying Reader. This permits reusing a ReadCloser
+// instead of allocating a new one.
+type Resetter interface {
+ // Reset discards any buffered data and resets the Resetter as if it was
+ // newly initialized with the given reader.
+ Reset(r io.Reader, dict []byte) error
+}
+
+// NewReader creates a new ReadCloser.
+// Reads from the returned ReadCloser read and decompress data from r.
+// If r does not implement io.ByteReader, the decompressor may read more
+// data than necessary from r.
+// It is the caller's responsibility to call Close on the ReadCloser when done.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReader(r io.Reader) (io.ReadCloser, error) {
+ return NewReaderDict(r, nil)
+}
+
+// NewReaderDict is like NewReader but uses a preset dictionary.
+// NewReaderDict ignores the dictionary if the compressed data does not refer to it.
+// If the compressed data refers to a different dictionary, NewReaderDict returns ErrDictionary.
+//
+// The ReadCloser returned by NewReaderDict also implements Resetter.
+func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) {
+ z := new(reader)
+ err := z.Reset(r, dict)
+ if err != nil {
+ return nil, err
+ }
+ return z, nil
+}
+
+func (z *reader) Read(p []byte) (int, error) {
+ if z.err != nil {
+ return 0, z.err
+ }
+
+ var n int
+ n, z.err = z.decompressor.Read(p)
+ z.digest.Write(p[0:n])
+ if z.err != io.EOF {
+ // In the normal case we return here.
+ return n, z.err
+ }
+
+ // Finished file; check checksum.
+ if _, err := io.ReadFull(z.r, z.scratch[0:4]); err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ z.err = err
+ return n, z.err
+ }
+ // ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).
+ checksum := binary.BigEndian.Uint32(z.scratch[:4])
+ if checksum != z.digest.Sum32() {
+ z.err = ErrChecksum
+ return n, z.err
+ }
+ return n, io.EOF
+}
+
+// Calling Close does not close the wrapped io.Reader originally passed to NewReader.
+// In order for the ZLIB checksum to be verified, the reader must be
+// fully consumed until the io.EOF.
+func (z *reader) Close() error {
+ if z.err != nil && z.err != io.EOF {
+ return z.err
+ }
+ z.err = z.decompressor.Close()
+ return z.err
+}
+
+func (z *reader) Reset(r io.Reader, dict []byte) error {
+ *z = reader{decompressor: z.decompressor}
+ if fr, ok := r.(flate.Reader); ok {
+ z.r = fr
+ } else {
+ z.r = bufio.NewReader(r)
+ }
+
+ // Read the header (RFC 1950 section 2.2.).
+ _, z.err = io.ReadFull(z.r, z.scratch[0:2])
+ if z.err != nil {
+ if z.err == io.EOF {
+ z.err = io.ErrUnexpectedEOF
+ }
+ return z.err
+ }
+ h := binary.BigEndian.Uint16(z.scratch[:2])
+ if (z.scratch[0]&0x0f != zlibDeflate) || (z.scratch[0]>>4 > zlibMaxWindow) || (h%31 != 0) {
+ z.err = ErrHeader
+ return z.err
+ }
+ haveDict := z.scratch[1]&0x20 != 0
+ if haveDict {
+ _, z.err = io.ReadFull(z.r, z.scratch[0:4])
+ if z.err != nil {
+ if z.err == io.EOF {
+ z.err = io.ErrUnexpectedEOF
+ }
+ return z.err
+ }
+ checksum := binary.BigEndian.Uint32(z.scratch[:4])
+ if checksum != adler32.Checksum(dict) {
+ z.err = ErrDictionary
+ return z.err
+ }
+ }
+
+ if z.decompressor == nil {
+ if haveDict {
+ z.decompressor = flate.NewReaderDict(z.r, dict)
+ } else {
+ z.decompressor = flate.NewReader(z.r)
+ }
+ } else {
+ z.decompressor.(flate.Resetter).Reset(z.r, dict)
+ }
+ z.digest = adler32.New()
+ return nil
+}
diff --git a/src/compress/zlib/reader_test.go b/src/compress/zlib/reader_test.go
new file mode 100644
index 0000000..20cec69
--- /dev/null
+++ b/src/compress/zlib/reader_test.go
@@ -0,0 +1,186 @@
+// Copyright 2009 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 zlib
+
+import (
+ "bytes"
+ "io"
+ "testing"
+)
+
+type zlibTest struct {
+ desc string
+ raw string
+ compressed []byte
+ dict []byte
+ err error
+}
+
+// Compare-to-golden test data was generated by the ZLIB example program at
+// https://www.zlib.net/zpipe.c
+
+var zlibTests = []zlibTest{
+ {
+ "truncated empty",
+ "",
+ []byte{},
+ nil,
+ io.ErrUnexpectedEOF,
+ },
+ {
+ "truncated dict",
+ "",
+ []byte{0x78, 0xbb},
+ []byte{0x00},
+ io.ErrUnexpectedEOF,
+ },
+ {
+ "truncated checksum",
+ "",
+ []byte{0x78, 0xbb, 0x00, 0x01, 0x00, 0x01, 0xca, 0x48,
+ 0xcd, 0xc9, 0xc9, 0xd7, 0x51, 0x28, 0xcf, 0x2f,
+ 0xca, 0x49, 0x01, 0x04, 0x00, 0x00, 0xff, 0xff,
+ },
+ []byte{0x00},
+ io.ErrUnexpectedEOF,
+ },
+ {
+ "empty",
+ "",
+ []byte{0x78, 0x9c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01},
+ nil,
+ nil,
+ },
+ {
+ "goodbye",
+ "goodbye, world",
+ []byte{
+ 0x78, 0x9c, 0x4b, 0xcf, 0xcf, 0x4f, 0x49, 0xaa,
+ 0x4c, 0xd5, 0x51, 0x28, 0xcf, 0x2f, 0xca, 0x49,
+ 0x01, 0x00, 0x28, 0xa5, 0x05, 0x5e,
+ },
+ nil,
+ nil,
+ },
+ {
+ "bad header (CINFO)",
+ "",
+ []byte{0x88, 0x98, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01},
+ nil,
+ ErrHeader,
+ },
+ {
+ "bad header (FCHECK)",
+ "",
+ []byte{0x78, 0x9f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01},
+ nil,
+ ErrHeader,
+ },
+ {
+ "bad checksum",
+ "",
+ []byte{0x78, 0x9c, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff},
+ nil,
+ ErrChecksum,
+ },
+ {
+ "not enough data",
+ "",
+ []byte{0x78, 0x9c, 0x03, 0x00, 0x00, 0x00},
+ nil,
+ io.ErrUnexpectedEOF,
+ },
+ {
+ "excess data is silently ignored",
+ "",
+ []byte{
+ 0x78, 0x9c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x78, 0x9c, 0xff,
+ },
+ nil,
+ nil,
+ },
+ {
+ "dictionary",
+ "Hello, World!\n",
+ []byte{
+ 0x78, 0xbb, 0x1c, 0x32, 0x04, 0x27, 0xf3, 0x00,
+ 0xb1, 0x75, 0x20, 0x1c, 0x45, 0x2e, 0x00, 0x24,
+ 0x12, 0x04, 0x74,
+ },
+ []byte{
+ 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x0a,
+ },
+ nil,
+ },
+ {
+ "wrong dictionary",
+ "",
+ []byte{
+ 0x78, 0xbb, 0x1c, 0x32, 0x04, 0x27, 0xf3, 0x00,
+ 0xb1, 0x75, 0x20, 0x1c, 0x45, 0x2e, 0x00, 0x24,
+ 0x12, 0x04, 0x74,
+ },
+ []byte{
+ 0x48, 0x65, 0x6c, 0x6c,
+ },
+ ErrDictionary,
+ },
+ {
+ "truncated zlib stream amid raw-block",
+ "hello",
+ []byte{
+ 0x78, 0x9c, 0x00, 0x0c, 0x00, 0xf3, 0xff, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
+ },
+ nil,
+ io.ErrUnexpectedEOF,
+ },
+ {
+ "truncated zlib stream amid fixed-block",
+ "He",
+ []byte{
+ 0x78, 0x9c, 0xf2, 0x48, 0xcd,
+ },
+ nil,
+ io.ErrUnexpectedEOF,
+ },
+}
+
+func TestDecompressor(t *testing.T) {
+ b := new(bytes.Buffer)
+ for _, tt := range zlibTests {
+ in := bytes.NewReader(tt.compressed)
+ zr, err := NewReaderDict(in, tt.dict)
+ if err != nil {
+ if err != tt.err {
+ t.Errorf("%s: NewReader: %s", tt.desc, err)
+ }
+ continue
+ }
+ defer zr.Close()
+
+ // Read and verify correctness of data.
+ b.Reset()
+ n, err := io.Copy(b, zr)
+ if err != nil {
+ if err != tt.err {
+ t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)
+ }
+ continue
+ }
+ s := b.String()
+ if s != tt.raw {
+ t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.desc, n, s, len(tt.raw), tt.raw)
+ }
+
+ // Check for sticky errors.
+ if n, err := zr.Read([]byte{0}); n != 0 || err != io.EOF {
+ t.Errorf("%s: Read() = (%d, %v), want (0, io.EOF)", tt.desc, n, err)
+ }
+ if err := zr.Close(); err != nil {
+ t.Errorf("%s: Close() = %v, want nil", tt.desc, err)
+ }
+ }
+}
diff --git a/src/compress/zlib/writer.go b/src/compress/zlib/writer.go
new file mode 100644
index 0000000..c65e80f
--- /dev/null
+++ b/src/compress/zlib/writer.go
@@ -0,0 +1,193 @@
+// Copyright 2009 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 zlib
+
+import (
+ "compress/flate"
+ "encoding/binary"
+ "fmt"
+ "hash"
+ "hash/adler32"
+ "io"
+)
+
+// These constants are copied from the flate package, so that code that imports
+// "compress/zlib" does not also have to import "compress/flate".
+const (
+ NoCompression = flate.NoCompression
+ BestSpeed = flate.BestSpeed
+ BestCompression = flate.BestCompression
+ DefaultCompression = flate.DefaultCompression
+ HuffmanOnly = flate.HuffmanOnly
+)
+
+// A Writer takes data written to it and writes the compressed
+// form of that data to an underlying writer (see NewWriter).
+type Writer struct {
+ w io.Writer
+ level int
+ dict []byte
+ compressor *flate.Writer
+ digest hash.Hash32
+ err error
+ scratch [4]byte
+ wroteHeader bool
+}
+
+// NewWriter creates a new Writer.
+// Writes to the returned Writer are compressed and written to w.
+//
+// It is the caller's responsibility to call Close on the Writer when done.
+// Writes may be buffered and not flushed until Close.
+func NewWriter(w io.Writer) *Writer {
+ z, _ := NewWriterLevelDict(w, DefaultCompression, nil)
+ return z
+}
+
+// NewWriterLevel is like NewWriter but specifies the compression level instead
+// of assuming DefaultCompression.
+//
+// The compression level can be DefaultCompression, NoCompression, HuffmanOnly
+// or any integer value between BestSpeed and BestCompression inclusive.
+// The error returned will be nil if the level is valid.
+func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
+ return NewWriterLevelDict(w, level, nil)
+}
+
+// NewWriterLevelDict is like NewWriterLevel but specifies a dictionary to
+// compress with.
+//
+// The dictionary may be nil. If not, its contents should not be modified until
+// the Writer is closed.
+func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*Writer, error) {
+ if level < HuffmanOnly || level > BestCompression {
+ return nil, fmt.Errorf("zlib: invalid compression level: %d", level)
+ }
+ return &Writer{
+ w: w,
+ level: level,
+ dict: dict,
+ }, nil
+}
+
+// Reset clears the state of the Writer z such that it is equivalent to its
+// initial state from NewWriterLevel or NewWriterLevelDict, but instead writing
+// to w.
+func (z *Writer) Reset(w io.Writer) {
+ z.w = w
+ // z.level and z.dict left unchanged.
+ if z.compressor != nil {
+ z.compressor.Reset(w)
+ }
+ if z.digest != nil {
+ z.digest.Reset()
+ }
+ z.err = nil
+ z.scratch = [4]byte{}
+ z.wroteHeader = false
+}
+
+// writeHeader writes the ZLIB header.
+func (z *Writer) writeHeader() (err error) {
+ z.wroteHeader = true
+ // ZLIB has a two-byte header (as documented in RFC 1950).
+ // The first four bits is the CINFO (compression info), which is 7 for the default deflate window size.
+ // The next four bits is the CM (compression method), which is 8 for deflate.
+ z.scratch[0] = 0x78
+ // The next two bits is the FLEVEL (compression level). The four values are:
+ // 0=fastest, 1=fast, 2=default, 3=best.
+ // The next bit, FDICT, is set if a dictionary is given.
+ // The final five FCHECK bits form a mod-31 checksum.
+ switch z.level {
+ case -2, 0, 1:
+ z.scratch[1] = 0 << 6
+ case 2, 3, 4, 5:
+ z.scratch[1] = 1 << 6
+ case 6, -1:
+ z.scratch[1] = 2 << 6
+ case 7, 8, 9:
+ z.scratch[1] = 3 << 6
+ default:
+ panic("unreachable")
+ }
+ if z.dict != nil {
+ z.scratch[1] |= 1 << 5
+ }
+ z.scratch[1] += uint8(31 - binary.BigEndian.Uint16(z.scratch[:2])%31)
+ if _, err = z.w.Write(z.scratch[0:2]); err != nil {
+ return err
+ }
+ if z.dict != nil {
+ // The next four bytes are the Adler-32 checksum of the dictionary.
+ binary.BigEndian.PutUint32(z.scratch[:], adler32.Checksum(z.dict))
+ if _, err = z.w.Write(z.scratch[0:4]); err != nil {
+ return err
+ }
+ }
+ if z.compressor == nil {
+ // Initialize deflater unless the Writer is being reused
+ // after a Reset call.
+ z.compressor, err = flate.NewWriterDict(z.w, z.level, z.dict)
+ if err != nil {
+ return err
+ }
+ z.digest = adler32.New()
+ }
+ return nil
+}
+
+// Write writes a compressed form of p to the underlying io.Writer. The
+// compressed bytes are not necessarily flushed until the Writer is closed or
+// explicitly flushed.
+func (z *Writer) Write(p []byte) (n int, err error) {
+ if !z.wroteHeader {
+ z.err = z.writeHeader()
+ }
+ if z.err != nil {
+ return 0, z.err
+ }
+ if len(p) == 0 {
+ return 0, nil
+ }
+ n, err = z.compressor.Write(p)
+ if err != nil {
+ z.err = err
+ return
+ }
+ z.digest.Write(p)
+ return
+}
+
+// Flush flushes the Writer to its underlying io.Writer.
+func (z *Writer) Flush() error {
+ if !z.wroteHeader {
+ z.err = z.writeHeader()
+ }
+ if z.err != nil {
+ return z.err
+ }
+ z.err = z.compressor.Flush()
+ return z.err
+}
+
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
+func (z *Writer) Close() error {
+ if !z.wroteHeader {
+ z.err = z.writeHeader()
+ }
+ if z.err != nil {
+ return z.err
+ }
+ z.err = z.compressor.Close()
+ if z.err != nil {
+ return z.err
+ }
+ checksum := z.digest.Sum32()
+ // ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).
+ binary.BigEndian.PutUint32(z.scratch[:], checksum)
+ _, z.err = z.w.Write(z.scratch[0:4])
+ return z.err
+}
diff --git a/src/compress/zlib/writer_test.go b/src/compress/zlib/writer_test.go
new file mode 100644
index 0000000..f0b3888
--- /dev/null
+++ b/src/compress/zlib/writer_test.go
@@ -0,0 +1,224 @@
+// Copyright 2009 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 zlib
+
+import (
+ "bytes"
+ "fmt"
+ "internal/testenv"
+ "io"
+ "os"
+ "testing"
+)
+
+var filenames = []string{
+ "../testdata/gettysburg.txt",
+ "../testdata/e.txt",
+ "../testdata/pi.txt",
+}
+
+var data = []string{
+ "test a reasonable sized string that can be compressed",
+}
+
+// Tests that compressing and then decompressing the given file at the given compression level and dictionary
+// yields equivalent bytes to the original file.
+func testFileLevelDict(t *testing.T, fn string, level int, d string) {
+ // Read the file, as golden output.
+ golden, err := os.Open(fn)
+ if err != nil {
+ t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
+ return
+ }
+ defer golden.Close()
+ b0, err0 := io.ReadAll(golden)
+ if err0 != nil {
+ t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err0)
+ return
+ }
+ testLevelDict(t, fn, b0, level, d)
+}
+
+func testLevelDict(t *testing.T, fn string, b0 []byte, level int, d string) {
+ // Make dictionary, if given.
+ var dict []byte
+ if d != "" {
+ dict = []byte(d)
+ }
+
+ // Push data through a pipe that compresses at the write end, and decompresses at the read end.
+ piper, pipew := io.Pipe()
+ defer piper.Close()
+ go func() {
+ defer pipew.Close()
+ zlibw, err := NewWriterLevelDict(pipew, level, dict)
+ if err != nil {
+ t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
+ return
+ }
+ defer zlibw.Close()
+ _, err = zlibw.Write(b0)
+ if err != nil {
+ t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
+ return
+ }
+ }()
+ zlibr, err := NewReaderDict(piper, dict)
+ if err != nil {
+ t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
+ return
+ }
+ defer zlibr.Close()
+
+ // Compare the decompressed data.
+ b1, err1 := io.ReadAll(zlibr)
+ if err1 != nil {
+ t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err1)
+ return
+ }
+ if len(b0) != len(b1) {
+ t.Errorf("%s (level=%d, dict=%q): length mismatch %d versus %d", fn, level, d, len(b0), len(b1))
+ return
+ }
+ for i := 0; i < len(b0); i++ {
+ if b0[i] != b1[i] {
+ t.Errorf("%s (level=%d, dict=%q): mismatch at %d, 0x%02x versus 0x%02x\n", fn, level, d, i, b0[i], b1[i])
+ return
+ }
+ }
+}
+
+func testFileLevelDictReset(t *testing.T, fn string, level int, dict []byte) {
+ var b0 []byte
+ var err error
+ if fn != "" {
+ b0, err = os.ReadFile(fn)
+ if err != nil {
+ t.Errorf("%s (level=%d): %v", fn, level, err)
+ return
+ }
+ }
+
+ // Compress once.
+ buf := new(bytes.Buffer)
+ var zlibw *Writer
+ if dict == nil {
+ zlibw, err = NewWriterLevel(buf, level)
+ } else {
+ zlibw, err = NewWriterLevelDict(buf, level, dict)
+ }
+ if err == nil {
+ _, err = zlibw.Write(b0)
+ }
+ if err == nil {
+ err = zlibw.Close()
+ }
+ if err != nil {
+ t.Errorf("%s (level=%d): %v", fn, level, err)
+ return
+ }
+ out := buf.String()
+
+ // Reset and compress again.
+ buf2 := new(bytes.Buffer)
+ zlibw.Reset(buf2)
+ _, err = zlibw.Write(b0)
+ if err == nil {
+ err = zlibw.Close()
+ }
+ if err != nil {
+ t.Errorf("%s (level=%d): %v", fn, level, err)
+ return
+ }
+ out2 := buf2.String()
+
+ if out2 != out {
+ t.Errorf("%s (level=%d): different output after reset (got %d bytes, expected %d",
+ fn, level, len(out2), len(out))
+ }
+}
+
+func TestWriter(t *testing.T) {
+ for i, s := range data {
+ b := []byte(s)
+ tag := fmt.Sprintf("#%d", i)
+ testLevelDict(t, tag, b, DefaultCompression, "")
+ testLevelDict(t, tag, b, NoCompression, "")
+ testLevelDict(t, tag, b, HuffmanOnly, "")
+ for level := BestSpeed; level <= BestCompression; level++ {
+ testLevelDict(t, tag, b, level, "")
+ }
+ }
+}
+
+func TestWriterBig(t *testing.T) {
+ for i, fn := range filenames {
+ testFileLevelDict(t, fn, DefaultCompression, "")
+ testFileLevelDict(t, fn, NoCompression, "")
+ testFileLevelDict(t, fn, HuffmanOnly, "")
+ for level := BestSpeed; level <= BestCompression; level++ {
+ testFileLevelDict(t, fn, level, "")
+ if level >= 1 && testing.Short() && testenv.Builder() == "" {
+ break
+ }
+ }
+ if i == 0 && testing.Short() && testenv.Builder() == "" {
+ break
+ }
+ }
+}
+
+func TestWriterDict(t *testing.T) {
+ const dictionary = "0123456789."
+ for i, fn := range filenames {
+ testFileLevelDict(t, fn, DefaultCompression, dictionary)
+ testFileLevelDict(t, fn, NoCompression, dictionary)
+ testFileLevelDict(t, fn, HuffmanOnly, dictionary)
+ for level := BestSpeed; level <= BestCompression; level++ {
+ testFileLevelDict(t, fn, level, dictionary)
+ if level >= 1 && testing.Short() && testenv.Builder() == "" {
+ break
+ }
+ }
+ if i == 0 && testing.Short() && testenv.Builder() == "" {
+ break
+ }
+ }
+}
+
+func TestWriterReset(t *testing.T) {
+ const dictionary = "0123456789."
+ for _, fn := range filenames {
+ testFileLevelDictReset(t, fn, NoCompression, nil)
+ testFileLevelDictReset(t, fn, DefaultCompression, nil)
+ testFileLevelDictReset(t, fn, HuffmanOnly, nil)
+ testFileLevelDictReset(t, fn, NoCompression, []byte(dictionary))
+ testFileLevelDictReset(t, fn, DefaultCompression, []byte(dictionary))
+ testFileLevelDictReset(t, fn, HuffmanOnly, []byte(dictionary))
+ if testing.Short() {
+ break
+ }
+ for level := BestSpeed; level <= BestCompression; level++ {
+ testFileLevelDictReset(t, fn, level, nil)
+ }
+ }
+}
+
+func TestWriterDictIsUsed(t *testing.T) {
+ var input = []byte("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
+ var buf bytes.Buffer
+ compressor, err := NewWriterLevelDict(&buf, BestCompression, input)
+ if err != nil {
+ t.Errorf("error in NewWriterLevelDict: %s", err)
+ return
+ }
+ compressor.Write(input)
+ compressor.Close()
+ const expectedMaxSize = 25
+ output := buf.Bytes()
+ if len(output) > expectedMaxSize {
+ t.Errorf("result too large (got %d, want <= %d bytes). Is the dictionary being used?", len(output), expectedMaxSize)
+ }
+}