aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/ulikunitz/xz/lzma/encoderdict.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ulikunitz/xz/lzma/encoderdict.go')
-rw-r--r--vendor/github.com/ulikunitz/xz/lzma/encoderdict.go149
1 files changed, 149 insertions, 0 deletions
diff --git a/vendor/github.com/ulikunitz/xz/lzma/encoderdict.go b/vendor/github.com/ulikunitz/xz/lzma/encoderdict.go
new file mode 100644
index 0000000..9d0fbc7
--- /dev/null
+++ b/vendor/github.com/ulikunitz/xz/lzma/encoderdict.go
@@ -0,0 +1,149 @@
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 "io"
11)
12
13// matcher is an interface that supports the identification of the next
14// operation.
15type matcher interface {
16 io.Writer
17 SetDict(d *encoderDict)
18 NextOp(rep [4]uint32) operation
19}
20
21// encoderDict provides the dictionary of the encoder. It includes an
22// addtional buffer atop of the actual dictionary.
23type encoderDict struct {
24 buf buffer
25 m matcher
26 head int64
27 capacity int
28 // preallocated array
29 data [maxMatchLen]byte
30}
31
32// newEncoderDict creates the encoder dictionary. The argument bufSize
33// defines the size of the additional buffer.
34func newEncoderDict(dictCap, bufSize int, m matcher) (d *encoderDict, err error) {
35 if !(1 <= dictCap && int64(dictCap) <= MaxDictCap) {
36 return nil, errors.New(
37 "lzma: dictionary capacity out of range")
38 }
39 if bufSize < 1 {
40 return nil, errors.New(
41 "lzma: buffer size must be larger than zero")
42 }
43 d = &encoderDict{
44 buf: *newBuffer(dictCap + bufSize),
45 capacity: dictCap,
46 m: m,
47 }
48 m.SetDict(d)
49 return d, nil
50}
51
52// Discard discards n bytes. Note that n must not be larger than
53// MaxMatchLen.
54func (d *encoderDict) Discard(n int) {
55 p := d.data[:n]
56 k, _ := d.buf.Read(p)
57 if k < n {
58 panic(fmt.Errorf("lzma: can't discard %d bytes", n))
59 }
60 d.head += int64(n)
61 d.m.Write(p)
62}
63
64// Len returns the data available in the encoder dictionary.
65func (d *encoderDict) Len() int {
66 n := d.buf.Available()
67 if int64(n) > d.head {
68 return int(d.head)
69 }
70 return n
71}
72
73// DictLen returns the actual length of data in the dictionary.
74func (d *encoderDict) DictLen() int {
75 if d.head < int64(d.capacity) {
76 return int(d.head)
77 }
78 return d.capacity
79}
80
81// Available returns the number of bytes that can be written by a
82// following Write call.
83func (d *encoderDict) Available() int {
84 return d.buf.Available() - d.DictLen()
85}
86
87// Write writes data into the dictionary buffer. Note that the position
88// of the dictionary head will not be moved. If there is not enough
89// space in the buffer ErrNoSpace will be returned.
90func (d *encoderDict) Write(p []byte) (n int, err error) {
91 m := d.Available()
92 if len(p) > m {
93 p = p[:m]
94 err = ErrNoSpace
95 }
96 var e error
97 if n, e = d.buf.Write(p); e != nil {
98 err = e
99 }
100 return n, err
101}
102
103// Pos returns the position of the head.
104func (d *encoderDict) Pos() int64 { return d.head }
105
106// ByteAt returns the byte at the given distance.
107func (d *encoderDict) ByteAt(distance int) byte {
108 if !(0 < distance && distance <= d.Len()) {
109 return 0
110 }
111 i := d.buf.rear - distance
112 if i < 0 {
113 i += len(d.buf.data)
114 }
115 return d.buf.data[i]
116}
117
118// CopyN copies the last n bytes from the dictionary into the provided
119// writer. This is used for copying uncompressed data into an
120// uncompressed segment.
121func (d *encoderDict) CopyN(w io.Writer, n int) (written int, err error) {
122 if n <= 0 {
123 return 0, nil
124 }
125 m := d.Len()
126 if n > m {
127 n = m
128 err = ErrNoSpace
129 }
130 i := d.buf.rear - n
131 var e error
132 if i < 0 {
133 i += len(d.buf.data)
134 if written, e = w.Write(d.buf.data[i:]); e != nil {
135 return written, e
136 }
137 i = 0
138 }
139 var k int
140 k, e = w.Write(d.buf.data[i:d.buf.rear])
141 written += k
142 if e != nil {
143 err = e
144 }
145 return written, err
146}
147
148// Buffered returns the number of bytes in the buffer.
149func (d *encoderDict) Buffered() int { return d.buf.Buffered() }