aboutsummaryrefslogtreecommitdiff
path: root/internal/compress/zlib/writer_header.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-05 17:36:48 +0800
committerGravatar Runxi Yu2026-03-05 18:38:29 +0800
commitbeabb6085d42cbb961e3a5dc217fdd840fee4b0d (patch)
tree64ea334e74925284228254631bd4e8bea89001d2 /internal/compress/zlib/writer_header.go
parentinternal/zlib: Unexport Reset (diff)
signatureNo 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.go71
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
+}