reader.go 3.1 KB

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