aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/ulikunitz/xz/lzma/decoderdict.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ulikunitz/xz/lzma/decoderdict.go')
-rw-r--r--vendor/github.com/ulikunitz/xz/lzma/decoderdict.go135
1 files changed, 135 insertions, 0 deletions
diff --git a/vendor/github.com/ulikunitz/xz/lzma/decoderdict.go b/vendor/github.com/ulikunitz/xz/lzma/decoderdict.go
new file mode 100644
index 0000000..564a12b
--- /dev/null
+++ b/vendor/github.com/ulikunitz/xz/lzma/decoderdict.go
@@ -0,0 +1,135 @@
1// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package lzma
6
7import (
8 "errors"
9 "fmt"
10)
11
12// decoderDict provides the dictionary for the decoder. The whole
13// dictionary is used as reader buffer.
14type decoderDict struct {
15 buf buffer
16 head int64
17}
18
19// newDecoderDict creates a new decoder dictionary. The whole dictionary
20// will be used as reader buffer.
21func newDecoderDict(dictCap int) (d *decoderDict, err error) {
22 // lower limit supports easy test cases
23 if !(1 <= dictCap && int64(dictCap) <= MaxDictCap) {
24 return nil, errors.New("lzma: dictCap out of range")
25 }
26 d = &decoderDict{buf: *newBuffer(dictCap)}
27 return d, nil
28}
29
30// Reset clears the dictionary. The read buffer is not changed, so the
31// buffered data can still be read.
32func (d *decoderDict) Reset() {
33 d.head = 0
34}
35
36// WriteByte writes a single byte into the dictionary. It is used to
37// write literals into the dictionary.
38func (d *decoderDict) WriteByte(c byte) error {
39 if err := d.buf.WriteByte(c); err != nil {
40 return err
41 }
42 d.head++
43 return nil
44}
45
46// pos returns the position of the dictionary head.
47func (d *decoderDict) pos() int64 { return d.head }
48
49// dictLen returns the actual length of the dictionary.
50func (d *decoderDict) dictLen() int {
51 capacity := d.buf.Cap()
52 if d.head >= int64(capacity) {
53 return capacity
54 }
55 return int(d.head)
56}
57
58// byteAt returns a byte stored in the dictionary. If the distance is
59// non-positive or exceeds the current length of the dictionary the zero
60// byte is returned.
61func (d *decoderDict) byteAt(dist int) byte {
62 if !(0 < dist && dist <= d.dictLen()) {
63 return 0
64 }
65 i := d.buf.front - dist
66 if i < 0 {
67 i += len(d.buf.data)
68 }
69 return d.buf.data[i]
70}
71
72// writeMatch writes the match at the top of the dictionary. The given
73// distance must point in the current dictionary and the length must not
74// exceed the maximum length 273 supported in LZMA.
75//
76// The error value ErrNoSpace indicates that no space is available in
77// the dictionary for writing. You need to read from the dictionary
78// first.
79func (d *decoderDict) writeMatch(dist int64, length int) error {
80 if !(0 < dist && dist <= int64(d.dictLen())) {
81 return errors.New("writeMatch: distance out of range")
82 }
83 if !(0 < length && length <= maxMatchLen) {
84 return errors.New("writeMatch: length out of range")
85 }
86 if length > d.buf.Available() {
87 return ErrNoSpace
88 }
89 d.head += int64(length)
90
91 i := d.buf.front - int(dist)
92 if i < 0 {
93 i += len(d.buf.data)
94 }
95 for length > 0 {
96 var p []byte
97 if i >= d.buf.front {
98 p = d.buf.data[i:]
99 i = 0
100 } else {
101 p = d.buf.data[i:d.buf.front]
102 i = d.buf.front
103 }
104 if len(p) > length {
105 p = p[:length]
106 }
107 if _, err := d.buf.Write(p); err != nil {
108 panic(fmt.Errorf("d.buf.Write returned error %s", err))
109 }
110 length -= len(p)
111 }
112 return nil
113}
114
115// Write writes the given bytes into the dictionary and advances the
116// head.
117func (d *decoderDict) Write(p []byte) (n int, err error) {
118 n, err = d.buf.Write(p)
119 d.head += int64(n)
120 return n, err
121}
122
123// Available returns the number of available bytes for writing into the
124// decoder dictionary.
125func (d *decoderDict) Available() int { return d.buf.Available() }
126
127// Read reads data from the buffer contained in the decoder dictionary.
128func (d *decoderDict) Read(p []byte) (n int, err error) { return d.buf.Read(p) }
129
130// Buffered returns the number of bytes currently buffered in the
131// decoder dictionary.
132func (d *decoderDict) buffered() int { return d.buf.Buffered() }
133
134// Peek gets data from the buffer without advancing the rear index.
135func (d *decoderDict) peek(p []byte) (n int, err error) { return d.buf.Peek(p) }