io.odin 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. // package io provides basic interfaces for generic data stream primitives.
  2. // The purpose of this package is wrap existing data structures and their
  3. // operations into an abstracted stream interface.
  4. package io
  5. import "core:intrinsics"
  6. import "core:unicode/utf8"
  7. // Seek whence values
  8. Seek_From :: enum {
  9. Start = 0, // seek relative to the origin of the file
  10. Current = 1, // seek relative to the current offset
  11. End = 2, // seek relative to the end
  12. }
  13. Error :: enum i32 {
  14. // No Error
  15. None = 0,
  16. // EOF is the error returned by `read` when no more input is available
  17. EOF,
  18. // Unexpected_EOF means that EOF was encountered in the middle of reading a fixed-sized block of data
  19. Unexpected_EOF,
  20. // Short_Write means that a write accepted fewer bytes than requested but failed to return an explicit error
  21. Short_Write,
  22. // Invalid_Write means that a write returned an impossible count
  23. Invalid_Write,
  24. // Short_Buffer means that a read required a longer buffer than was provided
  25. Short_Buffer,
  26. // No_Progress is returned by some implementations of `io.Reader` when many calls
  27. // to `read` have failed to return any data or error.
  28. // This is usually a signed of a broken `io.Reader` implementation
  29. No_Progress,
  30. Invalid_Whence,
  31. Invalid_Offset,
  32. Invalid_Unread,
  33. Negative_Read,
  34. Negative_Write,
  35. Negative_Count,
  36. Buffer_Full,
  37. // Unknown means that an error has occurred but cannot be categorized
  38. Unknown,
  39. // Empty is returned when a procedure has not been implemented for an io.Stream
  40. Empty = -1,
  41. }
  42. Close_Proc :: proc(using s: Stream) -> Error
  43. Flush_Proc :: proc(using s: Stream) -> Error
  44. Seek_Proc :: proc(using s: Stream, offset: i64, whence: Seek_From) -> (n: i64, err: Error)
  45. Size_Proc :: proc(using s: Stream) -> i64
  46. Read_Proc :: proc(using s: Stream, p: []byte) -> (n: int, err: Error)
  47. Read_At_Proc :: proc(using s: Stream, p: []byte, off: i64) -> (n: int, err: Error)
  48. Read_From_Proc :: proc(using s: Stream, r: Reader) -> (n: i64, err: Error)
  49. Read_Byte_Proc :: proc(using s: Stream) -> (byte, Error)
  50. Read_Rune_Proc :: proc(using s: Stream) -> (ch: rune, size: int, err: Error)
  51. Unread_Byte_Proc :: proc(using s: Stream) -> Error
  52. Unread_Rune_Proc :: proc(using s: Stream) -> Error
  53. Write_Proc :: proc(using s: Stream, p: []byte) -> (n: int, err: Error)
  54. Write_At_Proc :: proc(using s: Stream, p: []byte, off: i64) -> (n: int, err: Error)
  55. Write_To_Proc :: proc(using s: Stream, w: Writer) -> (n: i64, err: Error)
  56. Write_Byte_Proc :: proc(using s: Stream, c: byte) -> Error
  57. Write_Rune_Proc :: proc(using s: Stream, r: rune) -> (size: int, err: Error)
  58. Destroy_Proc :: proc(using s: Stream) -> Error
  59. Stream :: struct {
  60. using stream_vtable: ^Stream_VTable,
  61. stream_data: rawptr,
  62. }
  63. Stream_VTable :: struct {
  64. impl_close: Close_Proc,
  65. impl_flush: Flush_Proc,
  66. impl_seek: Seek_Proc,
  67. impl_size: Size_Proc,
  68. impl_read: Read_Proc,
  69. impl_read_at: Read_At_Proc,
  70. impl_read_byte: Read_Byte_Proc,
  71. impl_read_rune: Read_Rune_Proc,
  72. impl_write_to: Write_To_Proc,
  73. impl_write: Write_Proc,
  74. impl_write_at: Write_At_Proc,
  75. impl_write_byte: Write_Byte_Proc,
  76. impl_write_rune: Write_Rune_Proc,
  77. impl_read_from: Read_From_Proc,
  78. impl_unread_byte: Unread_Byte_Proc,
  79. impl_unread_rune: Unread_Rune_Proc,
  80. impl_destroy: Destroy_Proc,
  81. }
  82. Reader :: struct {using stream: Stream}
  83. Writer :: struct {using stream: Stream}
  84. Closer :: struct {using stream: Stream}
  85. Flusher :: struct {using stream: Stream}
  86. Seeker :: struct {using stream: Stream}
  87. Read_Writer :: struct {using stream: Stream}
  88. Read_Closer :: struct {using stream: Stream}
  89. Read_Write_Closer :: struct {using stream: Stream}
  90. Read_Write_Seeker :: struct {using stream: Stream}
  91. Write_Closer :: struct {using stream: Stream}
  92. Write_Seeker :: struct {using stream: Stream}
  93. Write_Flusher :: struct {using stream: Stream}
  94. Write_Flush_Closer :: struct {using stream: Stream}
  95. Reader_At :: struct {using stream: Stream}
  96. Writer_At :: struct {using stream: Stream}
  97. Reader_From :: struct {using stream: Stream}
  98. Writer_To :: struct {using stream: Stream}
  99. Byte_Reader :: struct {using stream: Stream}
  100. Byte_Scanner :: struct {using stream: Stream}
  101. Byte_Writer :: struct {using stream: Stream}
  102. Rune_Reader :: struct {using stream: Stream}
  103. Rune_Scanner :: struct {using stream: Stream}
  104. destroy :: proc(s: Stream) -> Error {
  105. close_err := close({s})
  106. if s.stream_vtable != nil && s.impl_destroy != nil {
  107. return s->impl_destroy()
  108. }
  109. if close_err != .None {
  110. return close_err
  111. }
  112. return .Empty
  113. }
  114. // read reads up to len(p) bytes into s. It returns the number of bytes read and any error if occurred.
  115. //
  116. // When read encounters an .EOF or error after successfully reading n > 0 bytes, it returns the number of
  117. // bytes read along with the error.
  118. read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) {
  119. if s.stream_vtable != nil && s.impl_read != nil {
  120. n, err = s->impl_read(p)
  121. if n_read != nil {
  122. n_read^ += n
  123. }
  124. return
  125. }
  126. return 0, .Empty
  127. }
  128. // write writes up to len(p) bytes into s. It returns the number of bytes written and any error if occurred.
  129. write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Error) {
  130. if s.stream_vtable != nil && s.impl_write != nil {
  131. n, err = s->impl_write(p)
  132. if n_written != nil {
  133. n_written^ += n
  134. }
  135. return
  136. }
  137. return 0, .Empty
  138. }
  139. // seek sets the offset of the next read or write to offset.
  140. //
  141. // .Start means seek relative to the origin of the file.
  142. // .Current means seek relative to the current offset.
  143. // .End means seek relative to the end.
  144. //
  145. // seek returns the new offset to the start of the file/stream, and any error if occurred.
  146. seek :: proc(s: Seeker, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
  147. if s.stream_vtable != nil && s.impl_seek != nil {
  148. return s->impl_seek(offset, whence)
  149. }
  150. return 0, .Empty
  151. }
  152. // The behaviour of close after the first call is stream implementation defined.
  153. // Different streams may document their own behaviour.
  154. close :: proc(s: Closer) -> Error {
  155. if s.stream_vtable != nil && s.impl_close != nil {
  156. return s->impl_close()
  157. }
  158. // Instead of .Empty, .None is fine in this case
  159. return .None
  160. }
  161. flush :: proc(s: Flusher) -> Error {
  162. if s.stream_vtable != nil && s.impl_flush != nil {
  163. return s->impl_flush()
  164. }
  165. // Instead of .Empty, .None is fine in this case
  166. return .None
  167. }
  168. // size returns the size of the stream. If the stream does not support querying its size, 0 will be returned.
  169. size :: proc(s: Stream) -> i64 {
  170. if s.stream_vtable == nil {
  171. return 0
  172. }
  173. if s.impl_size != nil {
  174. return s->impl_size()
  175. }
  176. if s.impl_seek == nil {
  177. return 0
  178. }
  179. curr, end: i64
  180. err: Error
  181. if curr, err = s->impl_seek(0, .Current); err != nil {
  182. return 0
  183. }
  184. if end, err = s->impl_seek(0, .End); err != nil {
  185. return 0
  186. }
  187. if _, err = s->impl_seek(curr, .Start); err != nil {
  188. return 0
  189. }
  190. return end
  191. }
  192. // read_at reads len(p) bytes into p starting with the provided offset in the underlying Reader_At stream r.
  193. // It returns the number of bytes read and any error if occurred.
  194. //
  195. // When read_at returns n < len(p), it returns a non-nil Error explaining why.
  196. //
  197. // If n == len(p), err may be either nil or .EOF
  198. read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: int, err: Error) {
  199. defer if n_read != nil {
  200. n_read^ += n
  201. }
  202. if r.stream_vtable == nil {
  203. return 0, .Empty
  204. }
  205. if r.impl_read_at != nil {
  206. return r->impl_read_at(p, offset)
  207. }
  208. if r.impl_seek == nil || r.impl_read == nil {
  209. return 0, .Empty
  210. }
  211. curr_offset := r->impl_seek(offset, .Current) or_return
  212. n, err = r->impl_read(p)
  213. _, err1 := r->impl_seek(curr_offset, .Start)
  214. if err1 != nil && err == nil {
  215. err = err1
  216. }
  217. return
  218. }
  219. // write_at writes len(p) bytes into p starting with the provided offset in the underlying Writer_At stream w.
  220. // It returns the number of bytes written and any error if occurred.
  221. //
  222. // If write_at is writing to a Writer_At which has a seek offset, then write_at should not affect the underlying
  223. // seek offset.
  224. write_at :: proc(w: Writer_At, p: []byte, offset: i64, n_written: ^int = nil) -> (n: int, err: Error) {
  225. defer if n_written != nil {
  226. n_written^ += n
  227. }
  228. if w.stream_vtable == nil {
  229. return 0, .Empty
  230. }
  231. if w.impl_write_at != nil {
  232. return w->impl_write_at(p, offset)
  233. }
  234. if w.impl_seek == nil || w.impl_write == nil {
  235. return 0, .Empty
  236. }
  237. curr_offset: i64
  238. curr_offset, err = w->impl_seek(offset, .Current)
  239. if err != nil {
  240. return 0, err
  241. }
  242. n, err = w->impl_write(p)
  243. _, err1 := w->impl_seek(curr_offset, .Start)
  244. if err1 != nil && err == nil {
  245. err = err1
  246. }
  247. return
  248. }
  249. write_to :: proc(r: Writer_To, w: Writer) -> (n: i64, err: Error) {
  250. if r.stream_vtable == nil || w.stream_vtable == nil {
  251. return 0, .Empty
  252. }
  253. if r.impl_write_to != nil {
  254. return r->impl_write_to(w)
  255. }
  256. return 0, .Empty
  257. }
  258. read_from :: proc(w: Reader_From, r: Reader) -> (n: i64, err: Error) {
  259. if r.stream_vtable == nil || w.stream_vtable == nil {
  260. return 0, .Empty
  261. }
  262. if r.impl_read_from != nil {
  263. return w->impl_read_from(r)
  264. }
  265. return 0, .Empty
  266. }
  267. // read_byte reads and returns the next byte from r.
  268. read_byte :: proc(r: Byte_Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
  269. defer if err == nil && n_read != nil {
  270. n_read^ += 1
  271. }
  272. if r.stream_vtable == nil {
  273. return 0, .Empty
  274. }
  275. if r.impl_read_byte != nil {
  276. return r->impl_read_byte()
  277. }
  278. if r.impl_read == nil {
  279. return 0, .Empty
  280. }
  281. buf: [1]byte
  282. _, err = r->impl_read(buf[:])
  283. return buf[0], err
  284. }
  285. write_byte :: proc{
  286. write_byte_to_byte_writer,
  287. write_byte_to_writer,
  288. }
  289. write_byte_to_byte_writer :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> Error {
  290. return _write_byte(w, c, n_written)
  291. }
  292. write_byte_to_writer :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error {
  293. return _write_byte(auto_cast w, c, n_written)
  294. }
  295. @(private)
  296. _write_byte :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> (err: Error) {
  297. defer if err == nil && n_written != nil {
  298. n_written^ += 1
  299. }
  300. if w.stream_vtable == nil {
  301. return .Empty
  302. }
  303. if w.impl_write_byte != nil {
  304. return w->impl_write_byte(c)
  305. }
  306. if w.impl_write == nil {
  307. return .Empty
  308. }
  309. b := [1]byte{c}
  310. _, err = w->impl_write(b[:])
  311. return err
  312. }
  313. // read_rune reads a single UTF-8 encoded Unicode codepoint and returns the rune and its size in bytes.
  314. read_rune :: proc(br: Rune_Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: Error) {
  315. defer if err == nil && n_read != nil {
  316. n_read^ += size
  317. }
  318. if br.stream_vtable == nil {
  319. return 0, 0, .Empty
  320. }
  321. if br.impl_read_rune != nil {
  322. return br->impl_read_rune()
  323. }
  324. if br.impl_read == nil {
  325. return 0, 0, .Empty
  326. }
  327. b: [utf8.UTF_MAX]byte
  328. _, err = br->impl_read(b[:1])
  329. s0 := b[0]
  330. ch = rune(s0)
  331. size = 1
  332. if err != nil {
  333. return
  334. }
  335. if ch < utf8.RUNE_SELF {
  336. return
  337. }
  338. x := utf8.accept_sizes[s0]
  339. if x >= 0xf0 {
  340. mask := rune(x) << 31 >> 31
  341. ch = ch &~ mask | utf8.RUNE_ERROR&mask
  342. return
  343. }
  344. sz := int(x&7)
  345. size, err = br->impl_read(b[1:sz])
  346. if err != nil || size+1 < sz {
  347. ch = utf8.RUNE_ERROR
  348. return
  349. }
  350. ch, size = utf8.decode_rune(b[:sz])
  351. return
  352. }
  353. unread_byte :: proc(s: Byte_Scanner) -> Error {
  354. if s.stream_vtable != nil && s.impl_unread_byte != nil {
  355. return s->impl_unread_byte()
  356. }
  357. return .Empty
  358. }
  359. unread_rune :: proc(s: Rune_Scanner) -> Error {
  360. if s.stream_vtable != nil && s.impl_unread_rune != nil {
  361. return s->impl_unread_rune()
  362. }
  363. return .Empty
  364. }
  365. // write_string writes the contents of the string s to w.
  366. write_string :: proc(s: Writer, str: string, n_written: ^int = nil) -> (n: int, err: Error) {
  367. return write(s, transmute([]byte)str, n_written)
  368. }
  369. // write_rune writes a UTF-8 encoded rune to w.
  370. write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err: Error) {
  371. defer if err == nil && n_written != nil {
  372. n_written^ += size
  373. }
  374. if s.stream_vtable != nil && s.impl_write_rune != nil {
  375. return s->impl_write_rune(r)
  376. }
  377. if r < utf8.RUNE_SELF {
  378. err = write_byte(s, byte(r))
  379. if err == nil {
  380. size = 1
  381. }
  382. return
  383. }
  384. buf, w := utf8.encode_rune(r)
  385. return write(s, buf[:w])
  386. }
  387. // read_full expected exactly len(buf) bytes from r into buf.
  388. read_full :: proc(r: Reader, buf: []byte) -> (n: int, err: Error) {
  389. return read_at_least(r, buf, len(buf))
  390. }
  391. // read_at_least reads from r into buf until it has read at least min bytes. It returns the number
  392. // of bytes copied and an error if fewer bytes were read. `.EOF` is only returned if no bytes were read.
  393. // `.Unexpected_EOF` is returned when an `.EOF ` is returned by the passed Reader after reading
  394. // fewer than min bytes. If len(buf) is less than min, `.Short_Buffer` is returned.
  395. read_at_least :: proc(r: Reader, buf: []byte, min: int) -> (n: int, err: Error) {
  396. if len(buf) < min {
  397. return 0, .Short_Buffer
  398. }
  399. for n < min && err == nil {
  400. nn: int
  401. nn, err = read(r, buf[n:])
  402. n += nn
  403. }
  404. if n >= min {
  405. err = nil
  406. } else if n > 0 && err == .EOF {
  407. err = .Unexpected_EOF
  408. }
  409. return
  410. }
  411. // copy copies from src to dst till either EOF is reached on src or an error occurs
  412. // It returns the number of bytes copied and the first error that occurred whilst copying, if any.
  413. copy :: proc(dst: Writer, src: Reader) -> (written: i64, err: Error) {
  414. return _copy_buffer(dst, src, nil)
  415. }
  416. // copy_buffer is the same as copy except that it stages through the provided buffer (if one is required)
  417. // rather than allocating a temporary one on the stack through `intrinsics.alloca`
  418. // If buf is `nil`, it is allocate through `intrinsics.alloca`; otherwise if it has zero length, it will panic
  419. copy_buffer :: proc(dst: Writer, src: Reader, buf: []byte) -> (written: i64, err: Error) {
  420. if buf != nil && len(buf) == 0 {
  421. panic("empty buffer in io.copy_buffer")
  422. }
  423. return _copy_buffer(dst, src, buf)
  424. }
  425. // copy_n copies n bytes (or till an error) from src to dst.
  426. // It returns the number of bytes copied and the first error that occurred whilst copying, if any.
  427. // On return, written == n IFF err == nil
  428. copy_n :: proc(dst: Writer, src: Reader, n: i64) -> (written: i64, err: Error) {
  429. nsrc := limited_reader_init(&Limited_Reader{}, src, n)
  430. written, err = copy(dst, nsrc)
  431. if written == n {
  432. return n, nil
  433. }
  434. if written < n && err == nil {
  435. // src stopped early and must have been an EOF
  436. err = .EOF
  437. }
  438. return
  439. }
  440. @(private)
  441. _copy_buffer :: proc(dst: Writer, src: Reader, buf: []byte) -> (written: i64, err: Error) {
  442. if dst.stream_vtable == nil || src.stream_vtable == nil {
  443. return 0, .Empty
  444. }
  445. if src.impl_write_to != nil {
  446. return src->impl_write_to(dst)
  447. }
  448. if src.impl_read_from != nil {
  449. return dst->impl_read_from(src)
  450. }
  451. buf := buf
  452. if buf == nil {
  453. DEFAULT_SIZE :: 4 * 1024
  454. size := DEFAULT_SIZE
  455. if src.stream_vtable == _limited_reader_vtable {
  456. l := (^Limited_Reader)(src.stream_data)
  457. if i64(size) > l.n {
  458. if l.n < 1 {
  459. size = 1
  460. } else {
  461. size = int(l.n)
  462. }
  463. }
  464. }
  465. // NOTE(bill): alloca is fine here
  466. buf = intrinsics.alloca(size, 2*align_of(rawptr))[:size]
  467. }
  468. for {
  469. nr, er := read(src, buf)
  470. if nr > 0 {
  471. nw, ew := write(dst, buf[0:nr])
  472. if nw > 0 {
  473. written += i64(nw)
  474. }
  475. if ew != nil {
  476. err = ew
  477. break
  478. }
  479. if nr != nw {
  480. err = .Short_Write
  481. break
  482. }
  483. }
  484. if er != nil {
  485. if er != .EOF {
  486. err = er
  487. }
  488. break
  489. }
  490. }
  491. return
  492. }