9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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
|
+
-
+
+
+
+
+
+
+
-
+
-
+
|
type context struct {
table [1 << 16]byte
buffer [1 << 3]byte
input []byte
hash uint16
}
type compressor func([]byte) error
// Returns a closure over the provided writer that compresses data when called.
func (w compressor) Write(data []byte) (int, error) {
return len(data), w(data)
}
// Returns an io.Writer implementation that wraps the provided io.Writer
// and compresses data according to the predictor algorithm
//
// It can buffer data as the predictor mandates 8-byte blocks with a header.
// A call with no data will force a flush.
func Compressor(writer io.Writer) func([]byte) error {
func Compressor(writer io.Writer) io.Writer {
var ctx context
ctx.input = ctx.buffer[:0]
// Forward declaration as it is required for recursion
var write func(data []byte) error
var write compressor
write = func(data []byte) error {
var (
blockSize int = 8
bufferLength int = len(ctx.input)
)
|
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
+
-
+
+
-
+
-
+
+
-
+
|
return nil
}
return write
}
// A function type alias so that it can have methods attached to it
type reader func([]byte) (int, error)
type decompressor func([]byte) (int, error)
// Required to implement io.Reader
func (r reader) Read(output []byte) (int, error) {
func (r decompressor) Read(output []byte) (int, error) {
return r(output)
}
// TODO - document
// Returns an io.Reader implementation that wraps the provided io.Reader
// and decompresses data according to the predictor algorithm
func Decompressor(wrapped io.Reader) io.Reader {
var ctx context
ctx.input = ctx.buffer[:0]
return reader(func(output []byte) (int, error) {
return decompressor(func(output []byte) (int, error) {
var (
err error
flags byte
readCount int
)
// Sanity check for space to read into
|