ref: d119343e8e7c83a56f87b05249ff0094aa2298a5
dir: /internal/flatex/window_decoder.go/
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
}