You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

io.c 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "io.h"
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. int l2_io_printf(struct l2_io_writer *w, const char *fmt, ...) {
  5. char buf[256];
  6. va_list va;
  7. va_start(va, fmt);
  8. int n = vsnprintf(buf, sizeof(buf), fmt, va);
  9. if (n < 0) {
  10. va_end(va);
  11. return n;
  12. } else if ((size_t)n + 1 < sizeof(buf)) {
  13. w->write(w, buf, n);
  14. va_end(va);
  15. return n;
  16. }
  17. // Yeah, this is slower, but it's just a fallback for when
  18. // the output of printf is stupidly long. That shouldn't happen much.
  19. char *buf2 = malloc(n + 1);
  20. if (buf2 == NULL) {
  21. va_end(va);
  22. return -1;
  23. }
  24. n = vsnprintf(buf2, n + 1, fmt, va);
  25. if (n < 0) {
  26. va_end(va);
  27. free(buf2);
  28. return -1;
  29. }
  30. w->write(w, buf2, n);
  31. va_end(va);
  32. free(buf2);
  33. return n;
  34. }
  35. void l2_bufio_reader_init(struct l2_bufio_reader *b, struct l2_io_reader *r) {
  36. b->r = r;
  37. b->len = 0;
  38. b->idx = 0;
  39. }
  40. void l2_bufio_shift(struct l2_bufio_reader *b) {
  41. if (b->idx > 0) {
  42. b->len -= b->idx;
  43. memmove(b->buf, b->buf + b->idx, b->len);
  44. }
  45. b->len += b->r->read(b->r, b->buf + b->len, sizeof(b->buf) - b->len);
  46. b->idx = 0;
  47. }
  48. int l2_bufio_shift_peek(struct l2_bufio_reader *b, size_t count) {
  49. size_t offset = count - 1;
  50. l2_bufio_shift(b);
  51. if (b->len <= offset) {
  52. return EOF;
  53. }
  54. return b->buf[offset];
  55. }
  56. int l2_bufio_shift_get(struct l2_bufio_reader *b) {
  57. l2_bufio_shift(b);
  58. if (b->len == 0) {
  59. return EOF;
  60. }
  61. return b->buf[b->idx++];
  62. }
  63. void l2_bufio_writer_init(struct l2_bufio_writer *b, struct l2_io_writer *w) {
  64. b->w = w;
  65. b->idx = 0;
  66. }
  67. void l2_bufio_flush(struct l2_bufio_writer *b) {
  68. if (b->idx == 0) return;
  69. b->w->write(b->w, b->buf, b->idx);
  70. b->idx = 0;
  71. }
  72. size_t l2_io_mem_read(struct l2_io_reader *self, void *buf, size_t len) {
  73. struct l2_io_mem_reader *r = (struct l2_io_mem_reader *)self;
  74. if (len >= r->len - r->idx) {
  75. len = r->len - r->idx;
  76. }
  77. memcpy(buf, (char *)r->mem + r->idx, len);
  78. r->idx += len;
  79. return len;
  80. }
  81. size_t l2_io_file_read(struct l2_io_reader *self, void *buf, size_t len) {
  82. struct l2_io_file_reader *r = (struct l2_io_file_reader *)self;
  83. return fread(buf, 1, len, r->f);
  84. }
  85. void l2_io_mem_write(struct l2_io_writer *self, const void *buf, size_t len) {
  86. struct l2_io_mem_writer *w = (struct l2_io_mem_writer *)self;
  87. size_t idx = w->len;
  88. if (w->len + len > w->size) {
  89. if (w->size == 0) w->size = 64;
  90. while (w->len + len > w->size) w->size *= 2;
  91. w->mem = realloc(w->mem, w->size);
  92. }
  93. w->len += len;
  94. memcpy((char *)w->mem + idx, buf, len);
  95. }
  96. void l2_io_file_write(struct l2_io_writer *self, const void *buf, size_t len) {
  97. struct l2_io_file_writer *w = (struct l2_io_file_writer *)self;
  98. fwrite(buf, 1, len, w->f);
  99. }