reader.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package lz4
  2. import (
  3. "io"
  4. "github.com/pierrec/lz4/internal/lz4errors"
  5. "github.com/pierrec/lz4/internal/lz4stream"
  6. )
  7. var readerStates = []aState{
  8. noState: newState,
  9. errorState: newState,
  10. newState: readState,
  11. readState: closedState,
  12. closedState: newState,
  13. }
  14. // NewReader returns a new LZ4 frame decoder.
  15. func NewReader(r io.Reader) *Reader {
  16. zr := &Reader{frame: lz4stream.NewFrame()}
  17. zr.state.init(readerStates)
  18. _ = zr.Apply(defaultOnBlockDone)
  19. zr.Reset(r)
  20. return zr
  21. }
  22. // Reader allows reading an LZ4 stream.
  23. type Reader struct {
  24. state _State
  25. src io.Reader // source reader
  26. frame *lz4stream.Frame // frame being read
  27. data []byte // pending data
  28. idx int // size of pending data
  29. handler func(int)
  30. }
  31. func (*Reader) private() {}
  32. func (r *Reader) Apply(options ...Option) (err error) {
  33. defer r.state.check(&err)
  34. switch r.state.state {
  35. case newState:
  36. case errorState:
  37. return r.state.err
  38. default:
  39. return lz4errors.ErrOptionClosedOrError
  40. }
  41. for _, o := range options {
  42. if err = o(r); err != nil {
  43. return
  44. }
  45. }
  46. return
  47. }
  48. // Size returns the size of the underlying uncompressed data, if set in the stream.
  49. func (r *Reader) Size() int {
  50. switch r.state.state {
  51. case readState, closedState:
  52. if r.frame.Descriptor.Flags.Size() {
  53. return int(r.frame.Descriptor.ContentSize)
  54. }
  55. }
  56. return 0
  57. }
  58. func (r *Reader) Read(buf []byte) (n int, err error) {
  59. defer r.state.check(&err)
  60. switch r.state.state {
  61. case readState:
  62. case closedState, errorState:
  63. return 0, r.state.err
  64. case newState:
  65. // First initialization.
  66. if err = r.frame.InitR(r.src); r.state.next(err) {
  67. return
  68. }
  69. r.data = r.frame.Descriptor.Flags.BlockSizeIndex().Get()
  70. default:
  71. return 0, r.state.fail()
  72. }
  73. if len(buf) == 0 {
  74. return
  75. }
  76. var bn int
  77. if r.idx > 0 {
  78. // Some left over data, use it.
  79. goto fillbuf
  80. }
  81. // No uncompressed data yet.
  82. r.data = r.data[:cap(r.data)]
  83. for len(buf) >= len(r.data) {
  84. // Input buffer large enough and no pending data: uncompress directly into it.
  85. switch bn, err = r.frame.Blocks.Block.Uncompress(r.frame, r.src, buf); err {
  86. case nil:
  87. r.handler(bn)
  88. n += bn
  89. buf = buf[bn:]
  90. case io.EOF:
  91. goto close
  92. default:
  93. return
  94. }
  95. }
  96. if n > 0 {
  97. // Some data was read, done for now.
  98. return
  99. }
  100. // Read the next block.
  101. switch bn, err = r.frame.Blocks.Block.Uncompress(r.frame, r.src, r.data); err {
  102. case nil:
  103. r.handler(bn)
  104. r.data = r.data[:bn]
  105. goto fillbuf
  106. case io.EOF:
  107. default:
  108. return
  109. }
  110. close:
  111. r.handler(bn)
  112. n += bn
  113. if er := r.frame.CloseR(r.src); er != nil {
  114. err = er
  115. }
  116. r.frame.Descriptor.Flags.BlockSizeIndex().Put(r.data)
  117. r.reset(nil)
  118. return
  119. fillbuf:
  120. bn = copy(buf, r.data[r.idx:])
  121. n += bn
  122. r.idx += bn
  123. if r.idx == len(r.data) {
  124. // All data read, get ready for the next Read.
  125. r.idx = 0
  126. }
  127. return
  128. }
  129. func (r *Reader) reset(reader io.Reader) {
  130. r.src = reader
  131. r.data = nil
  132. r.idx = 0
  133. }
  134. // Reset clears the state of the Reader r such that it is equivalent to its
  135. // initial state from NewReader, but instead writing to writer.
  136. // No access to reader is performed.
  137. //
  138. // w.Close must be called before Reset.
  139. func (r *Reader) Reset(reader io.Reader) {
  140. r.reset(reader)
  141. r.state.state = noState
  142. r.state.next(nil)
  143. }