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.
13 // matcher is an interface that supports the identification of the next
15 type matcher interface {
17 SetDict(d *encoderDict)
18 NextOp(rep [4]uint32) operation
21 // encoderDict provides the dictionary of the encoder. It includes an
22 // addtional buffer atop of the actual dictionary.
23 type encoderDict struct {
29 data [maxMatchLen]byte
32 // newEncoderDict creates the encoder dictionary. The argument bufSize
33 // defines the size of the additional buffer.
34 func 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")
40 return nil, errors.New(
41 "lzma: buffer size must be larger than zero")
44 buf: *newBuffer(dictCap + bufSize),
52 // Discard discards n bytes. Note that n must not be larger than
54 func (d *encoderDict) Discard(n int) {
58 panic(fmt.Errorf("lzma: can't discard %d bytes", n))
64 // Len returns the data available in the encoder dictionary.
65 func (d *encoderDict) Len() int {
66 n := d.buf.Available()
67 if int64(n) > d.head {
73 // DictLen returns the actual length of data in the dictionary.
74 func (d *encoderDict) DictLen() int {
75 if d.head < int64(d.capacity) {
81 // Available returns the number of bytes that can be written by a
82 // following Write call.
83 func (d *encoderDict) Available() int {
84 return d.buf.Available() - d.DictLen()
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.
90 func (d *encoderDict) Write(p []byte) (n int, err error) {
97 if n, e = d.buf.Write(p); e != nil {
103 // Pos returns the position of the head.
104 func (d *encoderDict) Pos() int64 { return d.head }
106 // ByteAt returns the byte at the given distance.
107 func (d *encoderDict) ByteAt(distance int) byte {
108 if !(0 < distance && distance <= d.Len()) {
111 i := d.buf.rear - distance
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.
121 func (d *encoderDict) CopyN(w io.Writer, n int) (written int, err error) {
134 if written, e = w.Write(d.buf.data[i:]); e != nil {
140 k, e = w.Write(d.buf.data[i:d.buf.rear])
148 // Buffered returns the number of bytes in the buffer.
149 func (d *encoderDict) Buffered() int { return d.buf.Buffered() }