decoderdict.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright 2014-2022 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. package lzma
  5. import (
  6. "errors"
  7. "fmt"
  8. )
  9. // decoderDict provides the dictionary for the decoder. The whole
  10. // dictionary is used as reader buffer.
  11. type decoderDict struct {
  12. buf buffer
  13. head int64
  14. }
  15. // newDecoderDict creates a new decoder dictionary. The whole dictionary
  16. // will be used as reader buffer.
  17. func newDecoderDict(dictCap int) (d *decoderDict, err error) {
  18. // lower limit supports easy test cases
  19. if !(1 <= dictCap && int64(dictCap) <= MaxDictCap) {
  20. return nil, errors.New("lzma: dictCap out of range")
  21. }
  22. d = &decoderDict{buf: *newBuffer(dictCap)}
  23. return d, nil
  24. }
  25. // Reset clears the dictionary. The read buffer is not changed, so the
  26. // buffered data can still be read.
  27. func (d *decoderDict) Reset() {
  28. d.head = 0
  29. }
  30. // WriteByte writes a single byte into the dictionary. It is used to
  31. // write literals into the dictionary.
  32. func (d *decoderDict) WriteByte(c byte) error {
  33. if err := d.buf.WriteByte(c); err != nil {
  34. return err
  35. }
  36. d.head++
  37. return nil
  38. }
  39. // pos returns the position of the dictionary head.
  40. func (d *decoderDict) pos() int64 { return d.head }
  41. // dictLen returns the actual length of the dictionary.
  42. func (d *decoderDict) dictLen() int {
  43. capacity := d.buf.Cap()
  44. if d.head >= int64(capacity) {
  45. return capacity
  46. }
  47. return int(d.head)
  48. }
  49. // byteAt returns a byte stored in the dictionary. If the distance is
  50. // non-positive or exceeds the current length of the dictionary the zero
  51. // byte is returned.
  52. func (d *decoderDict) byteAt(dist int) byte {
  53. if !(0 < dist && dist <= d.dictLen()) {
  54. return 0
  55. }
  56. i := d.buf.front - dist
  57. if i < 0 {
  58. i += len(d.buf.data)
  59. }
  60. return d.buf.data[i]
  61. }
  62. // writeMatch writes the match at the top of the dictionary. The given
  63. // distance must point in the current dictionary and the length must not
  64. // exceed the maximum length 273 supported in LZMA.
  65. //
  66. // The error value ErrNoSpace indicates that no space is available in
  67. // the dictionary for writing. You need to read from the dictionary
  68. // first.
  69. func (d *decoderDict) writeMatch(dist int64, length int) error {
  70. if !(0 < dist && dist <= int64(d.dictLen())) {
  71. return errors.New("writeMatch: distance out of range")
  72. }
  73. if !(0 < length && length <= maxMatchLen) {
  74. return errors.New("writeMatch: length out of range")
  75. }
  76. if length > d.buf.Available() {
  77. return ErrNoSpace
  78. }
  79. d.head += int64(length)
  80. i := d.buf.front - int(dist)
  81. if i < 0 {
  82. i += len(d.buf.data)
  83. }
  84. for length > 0 {
  85. var p []byte
  86. if i >= d.buf.front {
  87. p = d.buf.data[i:]
  88. i = 0
  89. } else {
  90. p = d.buf.data[i:d.buf.front]
  91. i = d.buf.front
  92. }
  93. if len(p) > length {
  94. p = p[:length]
  95. }
  96. if _, err := d.buf.Write(p); err != nil {
  97. panic(fmt.Errorf("d.buf.Write returned error %s", err))
  98. }
  99. length -= len(p)
  100. }
  101. return nil
  102. }
  103. // Write writes the given bytes into the dictionary and advances the
  104. // head.
  105. func (d *decoderDict) Write(p []byte) (n int, err error) {
  106. n, err = d.buf.Write(p)
  107. d.head += int64(n)
  108. return n, err
  109. }
  110. // Available returns the number of available bytes for writing into the
  111. // decoder dictionary.
  112. func (d *decoderDict) Available() int { return d.buf.Available() }
  113. // Read reads data from the buffer contained in the decoder dictionary.
  114. func (d *decoderDict) Read(p []byte) (n int, err error) { return d.buf.Read(p) }