reader.go 2.6 KB

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