選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

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