-
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
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
-
148
-
149
-
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
// Copyright 2014-2021 Ulrich Kunitz. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lzma
import (
"errors"
)
// buffer provides a circular buffer of bytes. If the front index equals
// the rear index the buffer is empty. As a consequence front cannot be
// equal rear for a full buffer. So a full buffer has a length that is
// one byte less the the length of the data slice.
type buffer struct {
data []byte
front int
rear int
}
// newBuffer creates a buffer with the given size.
func newBuffer(size int) *buffer {
return &buffer{data: make([]byte, size+1)}
}
// Cap returns the capacity of the buffer.
func (b *buffer) Cap() int {
return len(b.data) - 1
}
// Resets the buffer. The front and rear index are set to zero.
func (b *buffer) Reset() {
b.front = 0
b.rear = 0
}
// Buffered returns the number of bytes buffered.
func (b *buffer) Buffered() int {
delta := b.front - b.rear
if delta < 0 {
delta += len(b.data)
}
return delta
}
// Available returns the number of bytes available for writing.
func (b *buffer) Available() int {
delta := b.rear - 1 - b.front
if delta < 0 {
delta += len(b.data)
}
return delta
}
// addIndex adds a non-negative integer to the index i and returns the
// resulting index. The function takes care of wrapping the index as
// well as potential overflow situations.
func (b *buffer) addIndex(i int, n int) int {
// subtraction of len(b.data) prevents overflow
i += n - len(b.data)
if i < 0 {
i += len(b.data)
}
return i
}
// Read reads bytes from the buffer into p and returns the number of
// bytes read. The function never returns an error but might return less
// data than requested.
func (b *buffer) Read(p []byte) (n int, err error) {
n, err = b.Peek(p)
b.rear = b.addIndex(b.rear, n)
return n, err
}
// Peek reads bytes from the buffer into p without changing the buffer.
// Peek will never return an error but might return less data than
// requested.
func (b *buffer) Peek(p []byte) (n int, err error) {
m := b.Buffered()
n = len(p)
if m < n {
n = m
p = p[:n]
}
k := copy(p, b.data[b.rear:])
if k < n {
copy(p[k:], b.data)
}
return n, nil
}
// Discard skips the n next bytes to read from the buffer, returning the
// bytes discarded.
//
// If Discards skips fewer than n bytes, it returns an error.
func (b *buffer) Discard(n int) (discarded int, err error) {
if n < 0 {
return 0, errors.New("buffer.Discard: negative argument")
}
m := b.Buffered()
if m < n {
n = m
err = errors.New(
"buffer.Discard: discarded less bytes then requested")
}
b.rear = b.addIndex(b.rear, n)
return n, err
}
// ErrNoSpace indicates that there is insufficient space for the Write
// operation.
var ErrNoSpace = errors.New("insufficient space")
// Write puts data into the buffer. If less bytes are written than
// requested ErrNoSpace is returned.
func (b *buffer) Write(p []byte) (n int, err error) {
m := b.Available()
n = len(p)
if m < n {
n = m
p = p[:m]
err = ErrNoSpace
}
k := copy(b.data[b.front:], p)
if k < n {
copy(b.data, p[k:])
}
b.front = b.addIndex(b.front, n)
return n, err
}
// WriteByte writes a single byte into the buffer. The error ErrNoSpace
// is returned if no single byte is available in the buffer for writing.
func (b *buffer) WriteByte(c byte) error {
if b.Available() < 1 {
return ErrNoSpace
}
b.data[b.front] = c
b.front = b.addIndex(b.front, 1)
return nil
}
// prefixLen returns the length of the common prefix of a and b.
func prefixLen(a, b []byte) int {
if len(a) > len(b) {
a, b = b, a
}
for i, c := range a {
if b[i] != c {
return i
}
}
return len(a)
}
// matchLen returns the length of the common prefix for the given
// distance from the rear and the byte slice p.
func (b *buffer) matchLen(distance int, p []byte) int {
var n int
i := b.rear - distance
if i < 0 {
if n = prefixLen(p, b.data[len(b.data)+i:]); n < -i {
return n
}
p = p[n:]
i = 0
}
n += prefixLen(p, b.data[i:])
return n
}