reader.odin 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package bytes
  2. import "core:io"
  3. import "core:unicode/utf8"
  4. Reader :: struct {
  5. s: []byte, // read-only buffer
  6. i: i64, // current reading index
  7. prev_rune: int, // previous reading index of rune or < 0
  8. }
  9. reader_init :: proc(r: ^Reader, s: []byte) -> io.Stream {
  10. r.s = s
  11. r.i = 0
  12. r.prev_rune = -1
  13. return reader_to_stream(r)
  14. }
  15. reader_to_stream :: proc(r: ^Reader) -> (s: io.Stream) {
  16. s.data = r
  17. s.procedure = _reader_proc
  18. return
  19. }
  20. reader_length :: proc(r: ^Reader) -> int {
  21. if r.i >= i64(len(r.s)) {
  22. return 0
  23. }
  24. return int(i64(len(r.s)) - r.i)
  25. }
  26. reader_size :: proc(r: ^Reader) -> i64 {
  27. return i64(len(r.s))
  28. }
  29. reader_read :: proc(r: ^Reader, p: []byte) -> (n: int, err: io.Error) {
  30. if len(p) == 0 {
  31. return 0, nil
  32. }
  33. if r.i >= i64(len(r.s)) {
  34. return 0, .EOF
  35. }
  36. r.prev_rune = -1
  37. n = copy(p, r.s[r.i:])
  38. r.i += i64(n)
  39. return
  40. }
  41. reader_read_at :: proc(r: ^Reader, p: []byte, off: i64) -> (n: int, err: io.Error) {
  42. if len(p) == 0 {
  43. return 0, nil
  44. }
  45. if off < 0 {
  46. return 0, .Invalid_Offset
  47. }
  48. if off >= i64(len(r.s)) {
  49. return 0, .EOF
  50. }
  51. n = copy(p, r.s[off:])
  52. if n < len(p) {
  53. err = .EOF
  54. }
  55. return
  56. }
  57. reader_read_byte :: proc(r: ^Reader) -> (byte, io.Error) {
  58. r.prev_rune = -1
  59. if r.i >= i64(len(r.s)) {
  60. return 0, .EOF
  61. }
  62. b := r.s[r.i]
  63. r.i += 1
  64. return b, nil
  65. }
  66. reader_unread_byte :: proc(r: ^Reader) -> io.Error {
  67. if r.i <= 0 {
  68. return .Invalid_Unread
  69. }
  70. r.prev_rune = -1
  71. r.i -= 1
  72. return nil
  73. }
  74. reader_read_rune :: proc(r: ^Reader) -> (ch: rune, size: int, err: io.Error) {
  75. if r.i >= i64(len(r.s)) {
  76. r.prev_rune = -1
  77. return 0, 0, .EOF
  78. }
  79. r.prev_rune = int(r.i)
  80. if c := r.s[r.i]; c < utf8.RUNE_SELF {
  81. r.i += 1
  82. return rune(c), 1, nil
  83. }
  84. ch, size = utf8.decode_rune(r.s[r.i:])
  85. r.i += i64(size)
  86. return
  87. }
  88. reader_unread_rune :: proc(r: ^Reader) -> io.Error {
  89. if r.i <= 0 {
  90. return .Invalid_Unread
  91. }
  92. if r.prev_rune < 0 {
  93. return .Invalid_Unread
  94. }
  95. r.i = i64(r.prev_rune)
  96. r.prev_rune = -1
  97. return nil
  98. }
  99. reader_seek :: proc(r: ^Reader, offset: i64, whence: io.Seek_From) -> (i64, io.Error) {
  100. abs: i64
  101. switch whence {
  102. case .Start:
  103. abs = offset
  104. case .Current:
  105. abs = r.i + offset
  106. case .End:
  107. abs = i64(len(r.s)) + offset
  108. case:
  109. return 0, .Invalid_Whence
  110. }
  111. if abs < 0 {
  112. return 0, .Invalid_Offset
  113. }
  114. r.i = abs
  115. r.prev_rune = -1
  116. return abs, nil
  117. }
  118. reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
  119. r.prev_rune = -1
  120. if r.i >= i64(len(r.s)) {
  121. return 0, nil
  122. }
  123. s := r.s[r.i:]
  124. m: int
  125. m, err = io.write(w, s)
  126. if m > len(s) {
  127. panic("bytes.Reader.write_to: invalid io.write_string count")
  128. }
  129. r.i += i64(m)
  130. n = i64(m)
  131. if m != len(s) && err == nil {
  132. err = .Short_Write
  133. }
  134. return
  135. }
  136. @(private)
  137. _reader_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
  138. r := (^Reader)(stream_data)
  139. #partial switch mode {
  140. case .Read:
  141. return io._i64_err(reader_read(r, p))
  142. case .Read_At:
  143. return io._i64_err(reader_read_at(r, p, offset))
  144. case .Seek:
  145. n, err = reader_seek(r, offset, whence)
  146. return
  147. case .Size:
  148. n = reader_size(r)
  149. return
  150. case .Query:
  151. return io.query_utility({.Read, .Read_At, .Seek, .Size, .Query})
  152. }
  153. return 0, .Empty
  154. }