Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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 (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. b->w->write(b->w, b->buf, b->idx);
  69. b->idx = 0;
  70. }
  71. size_t l2_io_mem_read(struct l2_io_reader *self, void *buf, size_t len) {
  72. struct l2_io_mem_reader *r = (struct l2_io_mem_reader *)self;
  73. if (len >= r->len - r->idx) {
  74. len = r->len - r->idx;
  75. }
  76. memcpy(buf, r->mem + r->idx, len);
  77. r->idx += len;
  78. return len;
  79. }
  80. size_t l2_io_file_read(struct l2_io_reader *self, void *buf, size_t len) {
  81. struct l2_io_file_reader *r = (struct l2_io_file_reader *)self;
  82. return fread(buf, 1, len, r->f);
  83. }
  84. void l2_io_mem_write(struct l2_io_writer *self, const void *buf, size_t len) {
  85. struct l2_io_mem_writer *w = (struct l2_io_mem_writer *)self;
  86. size_t idx = w->len;
  87. w->len += len;
  88. w->mem = realloc(w->mem, w->len);
  89. memcpy((char *)w->mem + idx, buf, len);
  90. }
  91. void l2_io_file_write(struct l2_io_writer *self, const void *buf, size_t len) {
  92. struct l2_io_file_writer *w = (struct l2_io_file_writer *)self;
  93. fwrite(buf, 1, len, w->f);
  94. }