A clone of btpd with my configuration changes.
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.

104 lines
2.1 KiB

  1. #include <assert.h>
  2. #include <inttypes.h>
  3. #include <stdarg.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <strings.h>
  8. #include "iobuf.h"
  9. #include "subr.h"
  10. struct iobuf
  11. iobuf_init(size_t size)
  12. {
  13. struct iobuf iob;
  14. iob.size = size;
  15. iob.off = 0;
  16. iob.skip = 0;
  17. iob.error = (iob.buf = malloc(size)) == NULL ? 1 : 0;
  18. return iob;
  19. }
  20. void
  21. iobuf_free(struct iobuf *iob)
  22. {
  23. if (iob->buf != NULL)
  24. free(iob->buf - iob->skip);
  25. iob->buf = NULL;
  26. iob->error = 1;
  27. }
  28. void
  29. iobuf_consumed(struct iobuf *iob, size_t count)
  30. {
  31. if (iob->error)
  32. return;
  33. assert(count <= iob->off);
  34. iob->skip += count;
  35. iob->buf += count;
  36. iob->off -= count;
  37. }
  38. int
  39. iobuf_accommodate(struct iobuf *iob, size_t count)
  40. {
  41. if (iob->error)
  42. return 0;
  43. size_t esize = iob->size - (iob->skip + iob->off);
  44. if (esize >= count)
  45. return 1;
  46. else if (esize + iob->skip >= count) {
  47. bcopy(iob->buf, iob->buf - iob->skip, iob->off);
  48. iob->buf -= iob->skip;
  49. iob->skip = 0;
  50. return 1;
  51. } else {
  52. uint8_t *nbuf = realloc(iob->buf - iob->skip, iob->size + count);
  53. if (nbuf == NULL) {
  54. iob->error = 1;
  55. return 0;
  56. }
  57. iob->buf = nbuf + iob->skip;
  58. iob->size += count;
  59. return 1;
  60. }
  61. }
  62. int
  63. iobuf_print(struct iobuf *iob, const char *fmt, ...)
  64. {
  65. if (iob->error)
  66. return 0;
  67. int np;
  68. va_list ap;
  69. va_start(ap, fmt);
  70. np = vsnprintf(NULL, 0, fmt, ap);
  71. va_end(ap);
  72. if (!iobuf_accommodate(iob, np + 1))
  73. return 0;
  74. va_start(ap, fmt);
  75. vsnprintf(iob->buf + iob->off, np + 1, fmt, ap);
  76. va_end(ap);
  77. iob->off += np;
  78. return 1;
  79. }
  80. int
  81. iobuf_write(struct iobuf *iob, const void *buf, size_t count)
  82. {
  83. if (iob->error)
  84. return 0;
  85. if (!iobuf_accommodate(iob, count))
  86. return 0;
  87. bcopy(buf, iob->buf + iob->off, count);
  88. iob->off += count;
  89. return 1;
  90. }
  91. void *
  92. iobuf_find(struct iobuf *iob, const void *p, size_t plen)
  93. {
  94. return iob->error ? NULL : memfind(p, plen, iob->buf, iob->off);
  95. }