buffer.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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. )
  8. // buffer provides a circular buffer of bytes. If the front index equals
  9. // the rear index the buffer is empty. As a consequence front cannot be
  10. // equal rear for a full buffer. So a full buffer has a length that is
  11. // one byte less the the length of the data slice.
  12. type buffer struct {
  13. data []byte
  14. front int
  15. rear int
  16. }
  17. // newBuffer creates a buffer with the given size.
  18. func newBuffer(size int) *buffer {
  19. return &buffer{data: make([]byte, size+1)}
  20. }
  21. // Cap returns the capacity of the buffer.
  22. func (b *buffer) Cap() int {
  23. return len(b.data) - 1
  24. }
  25. // Resets the buffer. The front and rear index are set to zero.
  26. func (b *buffer) Reset() {
  27. b.front = 0
  28. b.rear = 0
  29. }
  30. // Buffered returns the number of bytes buffered.
  31. func (b *buffer) Buffered() int {
  32. delta := b.front - b.rear
  33. if delta < 0 {
  34. delta += len(b.data)
  35. }
  36. return delta
  37. }
  38. // Available returns the number of bytes available for writing.
  39. func (b *buffer) Available() int {
  40. delta := b.rear - 1 - b.front
  41. if delta < 0 {
  42. delta += len(b.data)
  43. }
  44. return delta
  45. }
  46. // addIndex adds a non-negative integer to the index i and returns the
  47. // resulting index. The function takes care of wrapping the index as
  48. // well as potential overflow situations.
  49. func (b *buffer) addIndex(i int, n int) int {
  50. // subtraction of len(b.data) prevents overflow
  51. i += n - len(b.data)
  52. if i < 0 {
  53. i += len(b.data)
  54. }
  55. return i
  56. }
  57. // Read reads bytes from the buffer into p and returns the number of
  58. // bytes read. The function never returns an error but might return less
  59. // data than requested.
  60. func (b *buffer) Read(p []byte) (n int, err error) {
  61. n, err = b.Peek(p)
  62. b.rear = b.addIndex(b.rear, n)
  63. return n, err
  64. }
  65. // Peek reads bytes from the buffer into p without changing the buffer.
  66. // Peek will never return an error but might return less data than
  67. // requested.
  68. func (b *buffer) Peek(p []byte) (n int, err error) {
  69. m := b.Buffered()
  70. n = len(p)
  71. if m < n {
  72. n = m
  73. p = p[:n]
  74. }
  75. k := copy(p, b.data[b.rear:])
  76. if k < n {
  77. copy(p[k:], b.data)
  78. }
  79. return n, nil
  80. }
  81. // Discard skips the n next bytes to read from the buffer, returning the
  82. // bytes discarded.
  83. //
  84. // If Discards skips fewer than n bytes, it returns an error.
  85. func (b *buffer) Discard(n int) (discarded int, err error) {
  86. if n < 0 {
  87. return 0, errors.New("buffer.Discard: negative argument")
  88. }
  89. m := b.Buffered()
  90. if m < n {
  91. n = m
  92. err = errors.New(
  93. "buffer.Discard: discarded less bytes then requested")
  94. }
  95. b.rear = b.addIndex(b.rear, n)
  96. return n, err
  97. }
  98. // ErrNoSpace indicates that there is insufficient space for the Write
  99. // operation.
  100. var ErrNoSpace = errors.New("insufficient space")
  101. // Write puts data into the buffer. If less bytes are written than
  102. // requested ErrNoSpace is returned.
  103. func (b *buffer) Write(p []byte) (n int, err error) {
  104. m := b.Available()
  105. n = len(p)
  106. if m < n {
  107. n = m
  108. p = p[:m]
  109. err = ErrNoSpace
  110. }
  111. k := copy(b.data[b.front:], p)
  112. if k < n {
  113. copy(b.data, p[k:])
  114. }
  115. b.front = b.addIndex(b.front, n)
  116. return n, err
  117. }
  118. // WriteByte writes a single byte into the buffer. The error ErrNoSpace
  119. // is returned if no single byte is available in the buffer for writing.
  120. func (b *buffer) WriteByte(c byte) error {
  121. if b.Available() < 1 {
  122. return ErrNoSpace
  123. }
  124. b.data[b.front] = c
  125. b.front = b.addIndex(b.front, 1)
  126. return nil
  127. }
  128. // prefixLen returns the length of the common prefix of a and b.
  129. func prefixLen(a, b []byte) int {
  130. if len(a) > len(b) {
  131. a, b = b, a
  132. }
  133. for i, c := range a {
  134. if b[i] != c {
  135. return i
  136. }
  137. }
  138. return len(a)
  139. }
  140. // matchLen returns the length of the common prefix for the given
  141. // distance from the rear and the byte slice p.
  142. func (b *buffer) matchLen(distance int, p []byte) int {
  143. var n int
  144. i := b.rear - distance
  145. if i < 0 {
  146. if n = prefixLen(p, b.data[len(b.data)+i:]); n < -i {
  147. return n
  148. }
  149. p = p[n:]
  150. i = 0
  151. }
  152. n += prefixLen(p, b.data[i:])
  153. return n
  154. }