io.odin 13 KB

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