diff options
Diffstat (limited to 'libgo/go/compress/gzip/gzip.go')
-rw-r--r-- | libgo/go/compress/gzip/gzip.go | 64 |
1 files changed, 22 insertions, 42 deletions
diff --git a/libgo/go/compress/gzip/gzip.go b/libgo/go/compress/gzip/gzip.go index 4d945e47fe..aafb442a66 100644 --- a/libgo/go/compress/gzip/gzip.go +++ b/libgo/go/compress/gzip/gzip.go @@ -8,9 +8,9 @@ import ( "compress/flate" "errors" "fmt" - "hash" "hash/crc32" "io" + "time" ) // These constants are copied from the flate package, so that code that imports @@ -20,6 +20,7 @@ const ( BestSpeed = flate.BestSpeed BestCompression = flate.BestCompression DefaultCompression = flate.DefaultCompression + HuffmanOnly = flate.HuffmanOnly ) // A Writer is an io.WriteCloser. @@ -30,8 +31,8 @@ type Writer struct { level int wroteHeader bool compressor *flate.Writer - digest hash.Hash32 - size uint32 + digest uint32 // CRC-32, IEEE polynomial (section 8) + size uint32 // Uncompressed size (section 2.3.1) closed bool buf [10]byte err error @@ -53,11 +54,11 @@ func NewWriter(w io.Writer) *Writer { // 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. +// 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 < DefaultCompression || level > BestCompression { + if level < HuffmanOnly || level > BestCompression { return nil, fmt.Errorf("gzip: invalid compression level: %d", level) } z := new(Writer) @@ -66,12 +67,6 @@ func NewWriterLevel(w io.Writer, level int) (*Writer, error) { } func (z *Writer) init(w io.Writer, level int) { - digest := z.digest - if digest != nil { - digest.Reset() - } else { - digest = crc32.NewIEEE() - } compressor := z.compressor if compressor != nil { compressor.Reset(w) @@ -82,7 +77,6 @@ func (z *Writer) init(w io.Writer, level int) { }, w: w, level: level, - digest: digest, compressor: compressor, } } @@ -95,26 +89,13 @@ func (z *Writer) Reset(w io.Writer) { z.init(w, z.level) } -// GZIP (RFC 1952) is little-endian, unlike ZLIB (RFC 1950). -func put2(p []byte, v uint16) { - p[0] = uint8(v >> 0) - p[1] = uint8(v >> 8) -} - -func put4(p []byte, v uint32) { - p[0] = uint8(v >> 0) - p[1] = uint8(v >> 8) - p[2] = uint8(v >> 16) - p[3] = uint8(v >> 24) -} - // 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") } - put2(z.buf[0:2], uint16(len(b))) - _, err := z.w.Write(z.buf[0:2]) + le.PutUint16(z.buf[:2], uint16(len(b))) + _, err := z.w.Write(z.buf[:2]) if err != nil { return err } @@ -149,7 +130,7 @@ func (z *Writer) writeString(s string) (err error) { } // GZIP strings are NUL-terminated. z.buf[0] = 0 - _, err = z.w.Write(z.buf[0:1]) + _, err = z.w.Write(z.buf[:1]) return err } @@ -163,10 +144,7 @@ func (z *Writer) Write(p []byte) (int, error) { // Write the GZIP header lazily. if !z.wroteHeader { z.wroteHeader = true - z.buf[0] = gzipID1 - z.buf[1] = gzipID2 - z.buf[2] = gzipDeflate - z.buf[3] = 0 + z.buf = [10]byte{0: gzipID1, 1: gzipID2, 2: gzipDeflate} if z.Extra != nil { z.buf[3] |= 0x04 } @@ -176,16 +154,18 @@ func (z *Writer) Write(p []byte) (int, error) { if z.Comment != "" { z.buf[3] |= 0x10 } - put4(z.buf[4:8], uint32(z.ModTime.Unix())) + 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 - } else { - z.buf[8] = 0 } z.buf[9] = z.OS - n, z.err = z.w.Write(z.buf[0:10]) + n, z.err = z.w.Write(z.buf[:10]) if z.err != nil { return n, z.err } @@ -212,7 +192,7 @@ func (z *Writer) Write(p []byte) (int, error) { } } z.size += uint32(len(p)) - z.digest.Write(p) + z.digest = crc32.Update(z.digest, crc32.IEEETable, p) n, z.err = z.compressor.Write(p) return n, z.err } @@ -262,8 +242,8 @@ func (z *Writer) Close() error { if z.err != nil { return z.err } - put4(z.buf[0:4], z.digest.Sum32()) - put4(z.buf[4:8], z.size) - _, z.err = z.w.Write(z.buf[0:8]) + 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 } |