diff options
| author | 2026-03-05 17:36:48 +0800 | |
|---|---|---|
| committer | 2026-03-05 18:38:29 +0800 | |
| commit | beabb6085d42cbb961e3a5dc217fdd840fee4b0d (patch) | |
| tree | 64ea334e74925284228254631bd4e8bea89001d2 /internal/compress/zlib/writer_header.go | |
| parent | internal/zlib: Unexport Reset (diff) | |
| signature | No signature | |
internal/compress: Import flate and such from klauspost/compress
Diffstat (limited to 'internal/compress/zlib/writer_header.go')
| -rw-r--r-- | internal/compress/zlib/writer_header.go | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/internal/compress/zlib/writer_header.go b/internal/compress/zlib/writer_header.go new file mode 100644 index 00000000..43d3bdf5 --- /dev/null +++ b/internal/compress/zlib/writer_header.go @@ -0,0 +1,71 @@ +// 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 ( + "encoding/binary" + + "codeberg.org/lindenii/furgit/internal/adler32" + "codeberg.org/lindenii/furgit/internal/compress/flate" +) + +// 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) //#nosec G115 + + _, err = z.w.Write(z.scratch[0:2]) + if 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)) + + _, err = z.w.Write(z.scratch[0:4]) + if 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 +} |
