aboutsummaryrefslogtreecommitdiff
path: root/internal/flatex/window_decoder.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2025-11-22 08:00:00 +0800
committerGravatar Runxi Yu2025-11-22 08:00:00 +0800
commit9b453a7cca6bb258a8ca939dc9696fabd77b1b7c (patch)
tree27f28df16a5f00f79021f9bd4d6d540435c9d2f8 /internal/flatex/window_decoder.go
parentflatex: Remove the stale readByte(s) wrappers and just directly index the buffer (diff)
signatureNo signature
zlib, flatex: Remove code related to dicts
Git never uses them
Diffstat (limited to 'internal/flatex/window_decoder.go')
-rw-r--r--internal/flatex/window_decoder.go101
1 files changed, 101 insertions, 0 deletions
diff --git a/internal/flatex/window_decoder.go b/internal/flatex/window_decoder.go
new file mode 100644
index 00000000..492c6a96
--- /dev/null
+++ b/internal/flatex/window_decoder.go
@@ -0,0 +1,101 @@
+package flatex
+
+// windowDecoder implements the sliding window used in decompression.
+type windowDecoder struct {
+ hist []byte
+
+ wrPos int
+ rdPos int
+ full bool
+}
+
+func (wd *windowDecoder) init(size int) {
+ *wd = windowDecoder{hist: wd.hist}
+
+ if cap(wd.hist) < size {
+ wd.hist = make([]byte, size)
+ }
+ wd.hist = wd.hist[:size]
+
+ wd.wrPos = 0
+ wd.rdPos = 0
+ wd.full = false
+}
+
+func (wd *windowDecoder) histSize() int {
+ if wd.full {
+ return len(wd.hist)
+ }
+ return wd.wrPos
+}
+
+func (wd *windowDecoder) availRead() int {
+ return wd.wrPos - wd.rdPos
+}
+
+func (wd *windowDecoder) availWrite() int {
+ return len(wd.hist) - wd.wrPos
+}
+
+func (wd *windowDecoder) writeSlice() []byte {
+ return wd.hist[wd.wrPos:]
+}
+
+func (wd *windowDecoder) writeMark(cnt int) {
+ wd.wrPos += cnt
+}
+
+func (wd *windowDecoder) writeByte(c byte) {
+ wd.hist[wd.wrPos] = c
+ wd.wrPos++
+}
+
+func (wd *windowDecoder) writeCopy(dist, length int) int {
+ dstBase := wd.wrPos
+ dstPos := dstBase
+ srcPos := dstPos - dist
+ endPos := dstPos + length
+ if endPos > len(wd.hist) {
+ endPos = len(wd.hist)
+ }
+
+ if srcPos < 0 {
+ srcPos += len(wd.hist)
+ dstPos += copy(wd.hist[dstPos:endPos], wd.hist[srcPos:])
+ srcPos = 0
+ }
+
+ for dstPos < endPos {
+ dstPos += copy(wd.hist[dstPos:endPos], wd.hist[srcPos:dstPos])
+ }
+
+ wd.wrPos = dstPos
+ return dstPos - dstBase
+}
+
+func (wd *windowDecoder) tryWriteCopy(dist, length int) int {
+ dstPos := wd.wrPos
+ endPos := dstPos + length
+ if dstPos < dist || endPos > len(wd.hist) {
+ return 0
+ }
+ dstBase := dstPos
+ srcPos := dstPos - dist
+
+ for dstPos < endPos {
+ dstPos += copy(wd.hist[dstPos:endPos], wd.hist[srcPos:dstPos])
+ }
+
+ wd.wrPos = dstPos
+ return dstPos - dstBase
+}
+
+func (wd *windowDecoder) readFlush() []byte {
+ toRead := wd.hist[wd.rdPos:wd.wrPos]
+ wd.rdPos = wd.wrPos
+ if wd.wrPos == len(wd.hist) {
+ wd.wrPos, wd.rdPos = 0, 0
+ wd.full = true
+ }
+ return toRead
+}