blob: 492c6a9606c4cf98b1552807448814aa114a4bd6 (
about) (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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
}
|