diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/flatex/decompress.go | 38 | ||||
| -rw-r--r-- | internal/flatex/decompress_bytes.go | 56 | ||||
| -rw-r--r-- | internal/flatex/huffman.go (renamed from internal/flatex/inflate.go) | 12 | ||||
| -rw-r--r-- | internal/flatex/slice_inflate.go | 11 |
4 files changed, 55 insertions, 62 deletions
diff --git a/internal/flatex/decompress.go b/internal/flatex/decompress.go new file mode 100644 index 00000000..641b6e7a --- /dev/null +++ b/internal/flatex/decompress.go @@ -0,0 +1,38 @@ +package flatex + +import ( + "io" + + "git.sr.ht/~runxiyu/furgit/internal/bufpool" +) + +func DecompressSized(src []byte, sizeHint int) (bufpool.Buffer, int, error) { + d := sliceInflaterPool.Get().(*sliceInflater) + defer sliceInflaterPool.Put(d) + + if err := d.reset(src); err != nil { + return bufpool.Buffer{}, 0, err + } + + out := bufpool.Borrow(sizeHint) + out.Resize(0) + + for { + if len(d.toRead) > 0 { + out.Append(d.toRead) + d.toRead = nil + continue + } + if d.err != nil { + if d.err == io.EOF { + return out, d.pos, nil + } + out.Release() + return bufpool.Buffer{}, 0, d.err + } + d.step(d) + if d.err != nil && len(d.toRead) == 0 { + d.toRead = d.window.readFlush() + } + } +} diff --git a/internal/flatex/decompress_bytes.go b/internal/flatex/decompress_bytes.go deleted file mode 100644 index 45a8b834..00000000 --- a/internal/flatex/decompress_bytes.go +++ /dev/null @@ -1,56 +0,0 @@ -package flatex - -import ( - "io" - "sync" - - "git.sr.ht/~runxiyu/furgit/internal/bufpool" -) - -type bufferDecompressor struct { - inflater sliceInflater -} - -var bufferDecompressorPool = sync.Pool{ - New: func() any { - fixedHuffmanDecoderInit() - d := &bufferDecompressor{ - inflater: sliceInflater{ - bits: new([maxNumLit + maxNumDist]int), - codebits: new([numCodes]int), - }, - } - return d - }, -} - -func DecompressSized(src []byte, sizeHint int) (bufpool.Buffer, int, error) { - d := bufferDecompressorPool.Get().(*bufferDecompressor) - defer bufferDecompressorPool.Put(d) - - if err := d.inflater.reset(src); err != nil { - return bufpool.Buffer{}, 0, err - } - - out := bufpool.Borrow(sizeHint) - out.Resize(0) - - for { - if len(d.inflater.toRead) > 0 { - out.Append(d.inflater.toRead) - d.inflater.toRead = nil - continue - } - if d.inflater.err != nil { - if d.inflater.err == io.EOF { - return out, d.inflater.pos, nil - } - out.Release() - return bufpool.Buffer{}, 0, d.inflater.err - } - d.inflater.step(&d.inflater) - if d.inflater.err != nil && len(d.inflater.toRead) == 0 { - d.inflater.toRead = d.inflater.window.readFlush() - } - } -} diff --git a/internal/flatex/inflate.go b/internal/flatex/huffman.go index a556dc42..32172dbb 100644 --- a/internal/flatex/inflate.go +++ b/internal/flatex/huffman.go @@ -26,12 +26,6 @@ const ( numCodes = 19 // number of codes in Huffman meta-code ) -var ( - // Initialize the fixedHuffmanDecoder only once upon first use. - fixedOnce sync.Once - fixedHuffmanDecoder huffmanDecoder -) - // A CorruptInputError reports the presence of corrupt input at a given offset. type CorruptInputError int64 @@ -224,6 +218,12 @@ func (h *huffmanDecoder) init(lengths []int) bool { // Compression with dynamic Huffman codes var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15} +var ( + // Initialize the fixedHuffmanDecoder only once upon first use. + fixedOnce sync.Once + fixedHuffmanDecoder huffmanDecoder +) + func fixedHuffmanDecoderInit() { fixedOnce.Do(func() { // These come from the RFC section 3.2.6. diff --git a/internal/flatex/slice_inflate.go b/internal/flatex/slice_inflate.go index 3e07e744..f9120143 100644 --- a/internal/flatex/slice_inflate.go +++ b/internal/flatex/slice_inflate.go @@ -3,6 +3,7 @@ package flatex import ( "io" "math/bits" + "sync" ) // sliceInflater is a specialized DEFLATE decoder that reads directly from an @@ -33,6 +34,16 @@ type sliceInflater struct { copyDist int } +var sliceInflaterPool = sync.Pool{ + New: func() any { + fixedHuffmanDecoderInit() + return &sliceInflater{ + bits: new([maxNumLit + maxNumDist]int), + codebits: new([numCodes]int), + } + }, +} + func (f *sliceInflater) reset(src []byte) error { bits := f.bits codebits := f.codebits |
