diff options
Diffstat (limited to 'vendor/github.com/ulikunitz/xz/lzma/decoderdict.go')
-rw-r--r-- | vendor/github.com/ulikunitz/xz/lzma/decoderdict.go | 135 |
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 | |||
5 | package lzma | ||
6 | |||
7 | import ( | ||
8 | "errors" | ||
9 | "fmt" | ||
10 | ) | ||
11 | |||
12 | // decoderDict provides the dictionary for the decoder. The whole | ||
13 | // dictionary is used as reader buffer. | ||
14 | type 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. | ||
21 | func 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. | ||
32 | func (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. | ||
38 | func (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. | ||
47 | func (d *decoderDict) pos() int64 { return d.head } | ||
48 | |||
49 | // dictLen returns the actual length of the dictionary. | ||
50 | func (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. | ||
61 | func (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. | ||
79 | func (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. | ||
117 | func (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. | ||
125 | func (d *decoderDict) Available() int { return d.buf.Available() } | ||
126 | |||
127 | // Read reads data from the buffer contained in the decoder dictionary. | ||
128 | func (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. | ||
132 | func (d *decoderDict) buffered() int { return d.buf.Buffered() } | ||
133 | |||
134 | // Peek gets data from the buffer without advancing the rear index. | ||
135 | func (d *decoderDict) peek(p []byte) (n int, err error) { return d.buf.Peek(p) } | ||