diff options
author | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
---|---|---|
committer | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
commit | f154da9e12608589e8d5f0508f908a0c3e88a1bb (patch) | |
tree | f8255d51e10c6f1e0ed69702200b966c9556a431 /src/pkg/compress/zlib | |
parent | 8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff) | |
download | golang-upstream/1.4.tar.gz |
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/pkg/compress/zlib')
-rw-r--r-- | src/pkg/compress/zlib/example_test.go | 37 | ||||
-rw-r--r-- | src/pkg/compress/zlib/reader.go | 132 | ||||
-rw-r--r-- | src/pkg/compress/zlib/reader_test.go | 127 | ||||
-rw-r--r-- | src/pkg/compress/zlib/writer.go | 198 | ||||
-rw-r--r-- | src/pkg/compress/zlib/writer_test.go | 205 |
5 files changed, 0 insertions, 699 deletions
diff --git a/src/pkg/compress/zlib/example_test.go b/src/pkg/compress/zlib/example_test.go deleted file mode 100644 index 70408895f..000000000 --- a/src/pkg/compress/zlib/example_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// 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/pkg/compress/zlib/reader.go b/src/pkg/compress/zlib/reader.go deleted file mode 100644 index 9e1aafda9..000000000 --- a/src/pkg/compress/zlib/reader.go +++ /dev/null @@ -1,132 +0,0 @@ -// 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" - "errors" - "hash" - "hash/adler32" - "io" -) - -const zlibDeflate = 8 - -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 -} - -// NewReader creates a new io.ReadCloser. -// Reads from the returned io.ReadCloser read and decompress data from r. -// The implementation buffers input and may read more data than necessary from r. -// It is the caller's responsibility to call Close on the ReadCloser when done. -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. -func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) { - z := new(reader) - if fr, ok := r.(flate.Reader); ok { - z.r = fr - } else { - z.r = bufio.NewReader(r) - } - _, err := io.ReadFull(z.r, z.scratch[0:2]) - if err != nil { - return nil, err - } - h := uint(z.scratch[0])<<8 | uint(z.scratch[1]) - if (z.scratch[0]&0x0f != zlibDeflate) || (h%31 != 0) { - return nil, ErrHeader - } - if z.scratch[1]&0x20 != 0 { - _, err = io.ReadFull(z.r, z.scratch[0:4]) - if err != nil { - return nil, err - } - checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3]) - if checksum != adler32.Checksum(dict) { - return nil, ErrDictionary - } - z.decompressor = flate.NewReaderDict(z.r, dict) - } else { - z.decompressor = flate.NewReader(z.r) - } - z.digest = adler32.New() - return z, nil -} - -func (z *reader) Read(p []byte) (n int, err error) { - if z.err != nil { - return 0, z.err - } - if len(p) == 0 { - return 0, nil - } - - n, err = z.decompressor.Read(p) - z.digest.Write(p[0:n]) - if n != 0 || err != io.EOF { - z.err = err - return - } - - // Finished file; check checksum. - if _, err := io.ReadFull(z.r, z.scratch[0:4]); err != nil { - z.err = err - return 0, err - } - // ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952). - checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3]) - if checksum != z.digest.Sum32() { - z.err = ErrChecksum - return 0, z.err - } - return -} - -// Calling Close does not close the wrapped io.Reader originally passed to NewReader. -func (z *reader) Close() error { - if z.err != nil { - return z.err - } - z.err = z.decompressor.Close() - return z.err -} diff --git a/src/pkg/compress/zlib/reader_test.go b/src/pkg/compress/zlib/reader_test.go deleted file mode 100644 index 218ccba14..000000000 --- a/src/pkg/compress/zlib/reader_test.go +++ /dev/null @@ -1,127 +0,0 @@ -// 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 -// http://www.zlib.net/zpipe.c - -var zlibTests = []zlibTest{ - { - "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", - "", - []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, - }, -} - -func TestDecompressor(t *testing.T) { - b := new(bytes.Buffer) - for _, tt := range zlibTests { - in := bytes.NewReader(tt.compressed) - zlib, err := NewReaderDict(in, tt.dict) - if err != nil { - if err != tt.err { - t.Errorf("%s: NewReader: %s", tt.desc, err) - } - continue - } - defer zlib.Close() - b.Reset() - n, err := io.Copy(b, zlib) - 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) - } - } -} diff --git a/src/pkg/compress/zlib/writer.go b/src/pkg/compress/zlib/writer.go deleted file mode 100644 index 3b4313a8b..000000000 --- a/src/pkg/compress/zlib/writer.go +++ /dev/null @@ -1,198 +0,0 @@ -// 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" - "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 -) - -// 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 WriteCloser 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, 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 < DefaultCompression || 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 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 - (uint16(z.scratch[0])<<8+uint16(z.scratch[1]))%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. - checksum := adler32.Checksum(z.dict) - z.scratch[0] = uint8(checksum >> 24) - z.scratch[1] = uint8(checksum >> 16) - z.scratch[2] = uint8(checksum >> 8) - z.scratch[3] = uint8(checksum >> 0) - 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). - z.scratch[0] = uint8(checksum >> 24) - z.scratch[1] = uint8(checksum >> 16) - z.scratch[2] = uint8(checksum >> 8) - z.scratch[3] = uint8(checksum >> 0) - _, z.err = z.w.Write(z.scratch[0:4]) - return z.err -} diff --git a/src/pkg/compress/zlib/writer_test.go b/src/pkg/compress/zlib/writer_test.go deleted file mode 100644 index 71ba81aaa..000000000 --- a/src/pkg/compress/zlib/writer_test.go +++ /dev/null @@ -1,205 +0,0 @@ -// 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" - "io" - "io/ioutil" - "os" - "testing" -) - -var filenames = []string{ - "../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 := ioutil.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 := ioutil.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 = ioutil.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, "") - for level := BestSpeed; level <= BestCompression; level++ { - testLevelDict(t, tag, b, level, "") - } - } -} - -func TestWriterBig(t *testing.T) { - for _, fn := range filenames { - testFileLevelDict(t, fn, DefaultCompression, "") - testFileLevelDict(t, fn, NoCompression, "") - for level := BestSpeed; level <= BestCompression; level++ { - testFileLevelDict(t, fn, level, "") - } - } -} - -func TestWriterDict(t *testing.T) { - const dictionary = "0123456789." - for _, fn := range filenames { - testFileLevelDict(t, fn, DefaultCompression, dictionary) - testFileLevelDict(t, fn, NoCompression, dictionary) - for level := BestSpeed; level <= BestCompression; level++ { - testFileLevelDict(t, fn, level, dictionary) - } - } -} - -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, NoCompression, []byte(dictionary)) - testFileLevelDictReset(t, fn, DefaultCompression, []byte(dictionary)) - if !testing.Short() { - 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) - } -} |