diff options
| author | 2026-03-04 09:55:00 +0800 | |
|---|---|---|
| committer | 2026-03-04 09:55:00 +0800 | |
| commit | 0a8c2632d02d19dc986f34f6ea457e4994977002 (patch) | |
| tree | e34a8dc3c14ff711713e7f8640f0ed8889094c9a /internal | |
| parent | config: Splitting (diff) | |
| signature | No signature | |
zlib: Split files
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/zlib/reader.go | 74 | ||||
| -rw-r--r-- | internal/zlib/reader_reset.go | 87 | ||||
| -rw-r--r-- | internal/zlib/writer.go | 61 | ||||
| -rw-r--r-- | internal/zlib/writer_header.go | 72 |
4 files changed, 159 insertions, 135 deletions
diff --git a/internal/zlib/reader.go b/internal/zlib/reader.go index e4babb9e..24db9875 100644 --- a/internal/zlib/reader.go +++ b/internal/zlib/reader.go @@ -34,15 +34,12 @@ and to read that data back: package zlib import ( - "bufio" "encoding/binary" "errors" "hash" "io" "sync" - "codeberg.org/lindenii/furgit/internal/adler32" - "github.com/klauspost/compress/flate" ) @@ -164,74 +161,3 @@ func (z *reader) Close() error { return nil } - -func (z *reader) Reset(r io.Reader, dict []byte) error { - *z = reader{decompressor: z.decompressor} - if fr, ok := r.(flate.Reader); ok { - z.r = fr - } else { - z.r = bufio.NewReader(r) - } - - // Read the header (RFC 1950 section 2.2.). - _, z.err = io.ReadFull(z.r, z.scratch[0:2]) - if z.err != nil { - if errors.Is(z.err, io.EOF) { - z.err = io.ErrUnexpectedEOF - } - - return z.err - } - - h := binary.BigEndian.Uint16(z.scratch[:2]) - if (z.scratch[0]&0x0f != zlibDeflate) || (z.scratch[0]>>4 > zlibMaxWindow) || (h%31 != 0) { - z.err = ErrHeader - - return z.err - } - - haveDict := z.scratch[1]&0x20 != 0 - if haveDict { - _, z.err = io.ReadFull(z.r, z.scratch[0:4]) - if z.err != nil { - if errors.Is(z.err, io.EOF) { - z.err = io.ErrUnexpectedEOF - } - - return z.err - } - - checksum := binary.BigEndian.Uint32(z.scratch[:4]) - if checksum != adler32.Checksum(dict) { - z.err = ErrDictionary - - return z.err - } - } - - if z.decompressor != nil { - resetter, ok := z.decompressor.(flate.Resetter) - if !ok { - panic("zlib: pooled decompressor does not implement flate.Resetter") - } - - z.err = resetter.Reset(z.r, dict) - if z.err != nil { - return z.err - } - - z.digest = adler32.New() - - return nil - } - - if haveDict { - z.decompressor = flate.NewReaderDict(z.r, dict) - } else { - z.decompressor = flate.NewReader(z.r) - } - - z.digest = adler32.New() - - return nil -} diff --git a/internal/zlib/reader_reset.go b/internal/zlib/reader_reset.go new file mode 100644 index 00000000..a39337f7 --- /dev/null +++ b/internal/zlib/reader_reset.go @@ -0,0 +1,87 @@ +// 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 ( + "bufio" + "encoding/binary" + "errors" + "io" + + "codeberg.org/lindenii/furgit/internal/adler32" + + "github.com/klauspost/compress/flate" +) + +func (z *reader) Reset(r io.Reader, dict []byte) error { + *z = reader{decompressor: z.decompressor} + if fr, ok := r.(flate.Reader); ok { + z.r = fr + } else { + z.r = bufio.NewReader(r) + } + + // Read the header (RFC 1950 section 2.2.). + _, z.err = io.ReadFull(z.r, z.scratch[0:2]) + if z.err != nil { + if errors.Is(z.err, io.EOF) { + z.err = io.ErrUnexpectedEOF + } + + return z.err + } + + h := binary.BigEndian.Uint16(z.scratch[:2]) + if (z.scratch[0]&0x0f != zlibDeflate) || (z.scratch[0]>>4 > zlibMaxWindow) || (h%31 != 0) { + z.err = ErrHeader + + return z.err + } + + haveDict := z.scratch[1]&0x20 != 0 + if haveDict { + _, z.err = io.ReadFull(z.r, z.scratch[0:4]) + if z.err != nil { + if errors.Is(z.err, io.EOF) { + z.err = io.ErrUnexpectedEOF + } + + return z.err + } + + checksum := binary.BigEndian.Uint32(z.scratch[:4]) + if checksum != adler32.Checksum(dict) { + z.err = ErrDictionary + + return z.err + } + } + + if z.decompressor != nil { + resetter, ok := z.decompressor.(flate.Resetter) + if !ok { + panic("zlib: pooled decompressor does not implement flate.Resetter") + } + + z.err = resetter.Reset(z.r, dict) + if z.err != nil { + return z.err + } + + z.digest = adler32.New() + + return nil + } + + if haveDict { + z.decompressor = flate.NewReaderDict(z.r, dict) + } else { + z.decompressor = flate.NewReader(z.r) + } + + z.digest = adler32.New() + + return nil +} diff --git a/internal/zlib/writer.go b/internal/zlib/writer.go index bfc52889..ba0a1f17 100644 --- a/internal/zlib/writer.go +++ b/internal/zlib/writer.go @@ -11,8 +11,6 @@ import ( "io" "sync" - "codeberg.org/lindenii/furgit/internal/adler32" - "github.com/klauspost/compress/flate" ) @@ -204,62 +202,3 @@ func (z *Writer) Close() error { return nil } - -// 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 -} diff --git a/internal/zlib/writer_header.go b/internal/zlib/writer_header.go new file mode 100644 index 00000000..29b02fb2 --- /dev/null +++ b/internal/zlib/writer_header.go @@ -0,0 +1,72 @@ +// 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" + + "github.com/klauspost/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 +} |
