/
runlengthbytewriter.go
119 lines (111 loc) · 2.31 KB
/
runlengthbytewriter.go
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package orc
import (
"io"
)
const (
MaxLiteralSize = 128
)
type RunLengthByteWriter struct {
io.ByteWriter
literals []byte
numLiterals int
repeat bool
tailRunLength int
minRepeatSize int
maxLiteralSize int
maxRepeatSize int
}
func NewRunLengthByteWriter(w io.ByteWriter) *RunLengthByteWriter {
return &RunLengthByteWriter{
ByteWriter: w,
literals: make([]byte, MaxLiteralSize),
minRepeatSize: MinRepeatSize,
maxLiteralSize: MaxLiteralSize,
maxRepeatSize: 127 + MinRepeatSize,
}
}
func (b *RunLengthByteWriter) writeValues() error {
if b.numLiterals != 0 {
if b.repeat {
err := b.ByteWriter.WriteByte(byte(b.numLiterals - b.minRepeatSize))
if err != nil {
return err
}
err = b.ByteWriter.WriteByte(b.literals[0])
if err != nil {
return err
}
} else {
err := b.ByteWriter.WriteByte(byte(-b.numLiterals))
if err != nil {
return err
}
for i := 0; i < b.numLiterals; i++ {
err = b.ByteWriter.WriteByte(b.literals[i])
if err != nil {
return err
}
}
}
b.repeat = false
b.tailRunLength = 0
b.numLiterals = 0
}
return nil
}
func (b *RunLengthByteWriter) Flush() error {
return b.writeValues()
}
func (b *RunLengthByteWriter) WriteByte(value byte) error {
if b.numLiterals == 0 {
b.literals[b.numLiterals] = value
b.numLiterals++
b.tailRunLength = 1
} else if b.repeat {
if value == b.literals[0] {
b.numLiterals++
if b.numLiterals == b.maxRepeatSize {
return b.writeValues()
}
} else {
err := b.writeValues()
if err != nil {
return err
}
b.literals[b.numLiterals] = value
b.numLiterals++
b.tailRunLength = 1
}
} else {
if value == b.literals[b.numLiterals-1] {
b.tailRunLength++
} else {
b.tailRunLength = 1
}
if b.tailRunLength == b.minRepeatSize {
if b.numLiterals+1 == b.minRepeatSize {
b.repeat = true
b.numLiterals++
} else {
b.numLiterals -= b.minRepeatSize - 1
err := b.writeValues()
if err != nil {
return err
}
b.literals[0] = value
b.repeat = true
b.numLiterals = b.minRepeatSize
}
} else {
b.literals[b.numLiterals] = value
b.numLiterals++
if b.numLiterals == b.maxLiteralSize {
return b.writeValues()
}
}
}
return nil
}
func (b *RunLengthByteWriter) Close() error {
return b.Flush()
}