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.h 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #ifndef L2_IO_H
  2. #define L2_IO_H
  3. #include <stdio.h>
  4. #include <string.h>
  5. #define L2_IO_BUFSIZ 1024
  6. struct l2_io_reader {
  7. size_t (*read)(struct l2_io_reader *self, char *buf, size_t len);
  8. };
  9. struct l2_io_writer {
  10. void (*write)(struct l2_io_writer *self, const char *buf, size_t len);
  11. };
  12. struct l2_bufio_reader {
  13. size_t bufsiz;
  14. size_t len;
  15. size_t idx;
  16. char buf[];
  17. };
  18. void l2_bufio_shift(struct l2_bufio_reader *b, struct l2_io_reader *r);
  19. int l2_bufio_shift_peek(struct l2_bufio_reader *b, struct l2_io_reader *r, size_t count);
  20. int l2_bufio_shift_get(struct l2_bufio_reader *b, struct l2_io_reader *r);
  21. int l2_bufio_peek(struct l2_bufio_reader *b, struct l2_io_reader *r, size_t count);
  22. int l2_bufio_get(struct l2_bufio_reader *b, struct l2_io_reader *r);
  23. struct l2_bufio_writer {
  24. size_t bufsiz;
  25. size_t idx;
  26. char buf[];
  27. };
  28. void l2_bufio_flush(struct l2_bufio_writer *b, struct l2_io_writer *w);
  29. void l2_bufio_put(struct l2_bufio_writer *b, struct l2_io_writer *w, char ch);
  30. void l2_bufio_put_n(struct l2_bufio_writer *b, struct l2_io_writer *w, const char *ptr, size_t len);
  31. /*
  32. * Useful readers and writers
  33. */
  34. struct l2_io_mem_reader {
  35. struct l2_io_reader r;
  36. size_t len;
  37. size_t idx;
  38. const char *mem;
  39. };
  40. size_t l2_io_mem_read(struct l2_io_reader *self, char *buf, size_t len);
  41. struct l2_io_file_reader {
  42. struct l2_io_reader r;
  43. FILE *f;
  44. };
  45. size_t l2_io_file_read(struct l2_io_reader *self, char *buf, size_t len);
  46. struct l2_io_mem_writer {
  47. struct l2_io_writer w;
  48. size_t len;
  49. char *mem;
  50. };
  51. void l2_io_mem_write(struct l2_io_writer *self, const char *buf, size_t len);
  52. struct l2_io_file_writer {
  53. struct l2_io_writer w;
  54. FILE *f;
  55. };
  56. void l2_io_file_write(struct l2_io_writer *self, const char *buf, size_t len);
  57. /*
  58. * Defined in the header to let the compiler inline
  59. */
  60. inline int l2_bufio_peek(struct l2_bufio_reader *b, struct l2_io_reader *r, size_t count) {\
  61. size_t offset = count - 1;
  62. if (b->idx + offset < b->len) {
  63. return b->buf[b->idx + offset];
  64. } else {
  65. return l2_bufio_shift_peek(b, r, count);
  66. }
  67. }
  68. inline int l2_bufio_get(struct l2_bufio_reader *b, struct l2_io_reader *r) {
  69. if (b->idx < b->bufsiz) {
  70. return b->buf[b->idx++];
  71. } else {
  72. return l2_bufio_shift_get(b, r);
  73. }
  74. }
  75. inline void l2_bufio_put(struct l2_bufio_writer *b, struct l2_io_writer *w, char ch) {
  76. if (b->idx >= b->bufsiz) {
  77. l2_bufio_flush(b, w);
  78. }
  79. b->buf[b->idx++] = ch;
  80. }
  81. inline void l2_bufio_put_n(struct l2_bufio_writer *b, struct l2_io_writer *w, const char *ptr, size_t len) {
  82. size_t freespace = b->bufsiz - b->idx;
  83. if (len < freespace) {
  84. memcpy(b->buf + b->idx, ptr, len);
  85. b->idx += len;
  86. } else {
  87. l2_bufio_flush(b, w);
  88. w->write(w, ptr, len);
  89. }
  90. }
  91. #endif