| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- // Copyright 2014-2022 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"
- "fmt"
- )
- // decoderDict provides the dictionary for the decoder. The whole
- // dictionary is used as reader buffer.
- type decoderDict struct {
- buf buffer
- head int64
- }
- // newDecoderDict creates a new decoder dictionary. The whole dictionary
- // will be used as reader buffer.
- func newDecoderDict(dictCap int) (d *decoderDict, err error) {
- // lower limit supports easy test cases
- if !(1 <= dictCap && int64(dictCap) <= MaxDictCap) {
- return nil, errors.New("lzma: dictCap out of range")
- }
- d = &decoderDict{buf: *newBuffer(dictCap)}
- return d, nil
- }
- // Reset clears the dictionary. The read buffer is not changed, so the
- // buffered data can still be read.
- func (d *decoderDict) Reset() {
- d.head = 0
- }
- // WriteByte writes a single byte into the dictionary. It is used to
- // write literals into the dictionary.
- func (d *decoderDict) WriteByte(c byte) error {
- if err := d.buf.WriteByte(c); err != nil {
- return err
- }
- d.head++
- return nil
- }
- // pos returns the position of the dictionary head.
- func (d *decoderDict) pos() int64 { return d.head }
- // dictLen returns the actual length of the dictionary.
- func (d *decoderDict) dictLen() int {
- capacity := d.buf.Cap()
- if d.head >= int64(capacity) {
- return capacity
- }
- return int(d.head)
- }
- // byteAt returns a byte stored in the dictionary. If the distance is
- // non-positive or exceeds the current length of the dictionary the zero
- // byte is returned.
- func (d *decoderDict) byteAt(dist int) byte {
- if !(0 < dist && dist <= d.dictLen()) {
- return 0
- }
- i := d.buf.front - dist
- if i < 0 {
- i += len(d.buf.data)
- }
- return d.buf.data[i]
- }
- // writeMatch writes the match at the top of the dictionary. The given
- // distance must point in the current dictionary and the length must not
- // exceed the maximum length 273 supported in LZMA.
- //
- // The error value ErrNoSpace indicates that no space is available in
- // the dictionary for writing. You need to read from the dictionary
- // first.
- func (d *decoderDict) writeMatch(dist int64, length int) error {
- if !(0 < dist && dist <= int64(d.dictLen())) {
- return errors.New("writeMatch: distance out of range")
- }
- if !(0 < length && length <= maxMatchLen) {
- return errors.New("writeMatch: length out of range")
- }
- if length > d.buf.Available() {
- return ErrNoSpace
- }
- d.head += int64(length)
- i := d.buf.front - int(dist)
- if i < 0 {
- i += len(d.buf.data)
- }
- for length > 0 {
- var p []byte
- if i >= d.buf.front {
- p = d.buf.data[i:]
- i = 0
- } else {
- p = d.buf.data[i:d.buf.front]
- i = d.buf.front
- }
- if len(p) > length {
- p = p[:length]
- }
- if _, err := d.buf.Write(p); err != nil {
- panic(fmt.Errorf("d.buf.Write returned error %s", err))
- }
- length -= len(p)
- }
- return nil
- }
- // Write writes the given bytes into the dictionary and advances the
- // head.
- func (d *decoderDict) Write(p []byte) (n int, err error) {
- n, err = d.buf.Write(p)
- d.head += int64(n)
- return n, err
- }
- // Available returns the number of available bytes for writing into the
- // decoder dictionary.
- func (d *decoderDict) Available() int { return d.buf.Available() }
- // Read reads data from the buffer contained in the decoder dictionary.
- func (d *decoderDict) Read(p []byte) (n int, err error) { return d.buf.Read(p) }
|