// 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 zlibimport ()// 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.NoCompressionBestSpeed = flate.BestSpeedBestCompression = flate.BestCompressionDefaultCompression = flate.DefaultCompressionHuffmanOnly = flate.HuffmanOnly)// A Writer takes data written to it and writes the compressed// form of that data to an underlying writer (see NewWriter).typeWriterstruct { 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 ( io.Writer) *Writer { , := NewWriterLevelDict(, DefaultCompression, nil)return}// 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 ( io.Writer, int) (*Writer, error) {returnNewWriterLevelDict(, , 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 ( io.Writer, int, []byte) (*Writer, error) {if < HuffmanOnly || > BestCompression {returnnil, fmt.Errorf("zlib: invalid compression level: %d", ) }return &Writer{w: ,level: ,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 ( *Writer) ( io.Writer) { .w = // z.level and z.dict left unchanged.if .compressor != nil { .compressor.Reset() }if .digest != nil { .digest.Reset() } .err = nil .scratch = [4]byte{} .wroteHeader = false}// writeHeader writes the ZLIB header.func ( *Writer) () ( error) { .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. .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 .level {case -2, 0, 1: .scratch[1] = 0 << 6case2, 3, 4, 5: .scratch[1] = 1 << 6case6, -1: .scratch[1] = 2 << 6case7, 8, 9: .scratch[1] = 3 << 6default:panic("unreachable") }if .dict != nil { .scratch[1] |= 1 << 5 } .scratch[1] += uint8(31 - binary.BigEndian.Uint16(.scratch[:2])%31)if _, = .w.Write(.scratch[0:2]); != nil {return }if .dict != nil {// The next four bytes are the Adler-32 checksum of the dictionary.binary.BigEndian.PutUint32(.scratch[:], adler32.Checksum(.dict))if _, = .w.Write(.scratch[0:4]); != nil {return } }if .compressor == nil {// Initialize deflater unless the Writer is being reused // after a Reset call. .compressor, = flate.NewWriterDict(.w, .level, .dict)if != nil {return } .digest = adler32.New() }returnnil}// 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 ( *Writer) ( []byte) ( int, error) {if !.wroteHeader { .err = .writeHeader() }if .err != nil {return0, .err }iflen() == 0 {return0, nil } , = .compressor.Write()if != nil { .err = return } .digest.Write()return}// Flush flushes the Writer to its underlying io.Writer.func ( *Writer) () error {if !.wroteHeader { .err = .writeHeader() }if .err != nil {return .err } .err = .compressor.Flush()return .err}// Close closes the Writer, flushing any unwritten data to the underlying// io.Writer, but does not close the underlying io.Writer.func ( *Writer) () error {if !.wroteHeader { .err = .writeHeader() }if .err != nil {return .err } .err = .compressor.Close()if .err != nil {return .err } := .digest.Sum32()// ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).binary.BigEndian.PutUint32(.scratch[:], ) _, .err = .w.Write(.scratch[0:4])return .err}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.