buf.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /*
  2. * buf.c
  3. *
  4. * This file provides the implementation of a buf class
  5. */
  6. #include "private.h"
  7. #include "lub/argv.h"
  8. #include "lub/string.h"
  9. #include "lub/ctype.h"
  10. #include <assert.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <stdio.h>
  14. #include <unistd.h>
  15. #define KONF_BUF_CHUNK 1024
  16. /*-------------------------------------------------------- */
  17. int konf_buf_compare(const void *first, const void *second)
  18. {
  19. const konf_buf_t *f = (const konf_buf_t *)first;
  20. const konf_buf_t *s = (const konf_buf_t *)second;
  21. return (f->fd - s->fd);
  22. }
  23. /*-------------------------------------------------------- */
  24. static void konf_buf_init(konf_buf_t * this, int fd)
  25. {
  26. this->fd = fd;
  27. this->buf = malloc(KONF_BUF_CHUNK);
  28. this->size = KONF_BUF_CHUNK;
  29. this->pos = 0;
  30. this->rpos = 0;
  31. this->data = NULL;
  32. }
  33. /*--------------------------------------------------------- */
  34. static void konf_buf_fini(konf_buf_t * this)
  35. {
  36. free(this->buf);
  37. }
  38. /*--------------------------------------------------------- */
  39. konf_buf_t *konf_buf_new(int fd)
  40. {
  41. konf_buf_t *this = malloc(sizeof(konf_buf_t));
  42. if (this)
  43. konf_buf_init(this, fd);
  44. return this;
  45. }
  46. /*-------------------------------------------------------- */
  47. void konf_buf_delete(void *data)
  48. {
  49. konf_buf_t *this = (konf_buf_t *)data;
  50. konf_buf_fini(this);
  51. free(this);
  52. }
  53. /*--------------------------------------------------------- */
  54. static int konf_buf_realloc(konf_buf_t *this, int addsize)
  55. {
  56. int chunk = KONF_BUF_CHUNK;
  57. char *tmpbuf;
  58. if (addsize > chunk)
  59. chunk = addsize;
  60. if ((this->size - this->pos) < chunk) {
  61. tmpbuf = realloc(this->buf, this->size + chunk);
  62. this->buf = tmpbuf;
  63. this->size += chunk;
  64. }
  65. return this->size;
  66. }
  67. /*--------------------------------------------------------- */
  68. int konf_buf_add(konf_buf_t *this, void *str, size_t len)
  69. {
  70. char *buffer;
  71. konf_buf_realloc(this, len);
  72. buffer = this->buf + this->pos;
  73. memcpy(buffer, str, len);
  74. this->pos += len;
  75. return len;
  76. }
  77. /*--------------------------------------------------------- */
  78. int konf_buf_read(konf_buf_t *this)
  79. {
  80. char *buffer;
  81. int buffer_size;
  82. int nbytes;
  83. konf_buf_realloc(this, 0);
  84. buffer_size = this->size - this->pos;
  85. buffer = this->buf + this->pos;
  86. nbytes = read(this->fd, buffer, buffer_size);
  87. if (nbytes > 0)
  88. this->pos += nbytes;
  89. return nbytes;
  90. }
  91. /*--------------------------------------------------------- */
  92. char * konf_buf_string(char *buf, int len)
  93. {
  94. int i;
  95. char *str;
  96. for (i = 0; i < len; i++) {
  97. if (('\0' == buf[i]) ||
  98. ('\n' == buf[i]))
  99. break;
  100. }
  101. if (i >= len)
  102. return NULL;
  103. str = malloc(i + 1);
  104. memcpy(str, buf, i + 1);
  105. str[i] = '\0';
  106. return str;
  107. }
  108. /*--------------------------------------------------------- */
  109. char * konf_buf_parse(konf_buf_t *this)
  110. {
  111. char * str = NULL;
  112. /* Search the buffer for the string */
  113. str = konf_buf_string(this->buf, this->pos);
  114. /* Remove parsed string from the buffer */
  115. if (str) {
  116. int len = strlen(str) + 1;
  117. memmove(this->buf, &this->buf[len], this->pos - len);
  118. this->pos -= len;
  119. if (this->rpos >= len)
  120. this->rpos -= len;
  121. else
  122. this->rpos = 0;
  123. }
  124. /* Make buffer shorter */
  125. if ((this->size - this->pos) > (2 * KONF_BUF_CHUNK)) {
  126. char *tmpbuf;
  127. tmpbuf = realloc(this->buf, this->size - KONF_BUF_CHUNK);
  128. this->buf = tmpbuf;
  129. this->size -= KONF_BUF_CHUNK;
  130. }
  131. return str;
  132. }
  133. /*--------------------------------------------------------- */
  134. char * konf_buf_preparse(konf_buf_t *this)
  135. {
  136. char * str = NULL;
  137. str = konf_buf_string(this->buf + this->rpos, this->pos - this->rpos);
  138. if (str)
  139. this->rpos += (strlen(str) + 1);
  140. return str;
  141. }
  142. /*--------------------------------------------------------- */
  143. int konf_buf_lseek(konf_buf_t *this, int newpos)
  144. {
  145. if (newpos > this->pos)
  146. return -1;
  147. this->rpos = newpos;
  148. return newpos;
  149. }
  150. /*--------------------------------------------------------- */
  151. int konf_buf__get_fd(const konf_buf_t * this)
  152. {
  153. return this->fd;
  154. }
  155. /*--------------------------------------------------------- */
  156. int konf_buf__get_len(const konf_buf_t *this)
  157. {
  158. return this->pos;
  159. }
  160. /*--------------------------------------------------------- */
  161. char * konf_buf__dup_line(const konf_buf_t *this)
  162. {
  163. char *str;
  164. str = malloc(this->pos + 1);
  165. memcpy(str, this->buf, this->pos);
  166. str[this->pos] = '\0';
  167. return str;
  168. }
  169. /*--------------------------------------------------------- */
  170. char * konf_buf__get_buf(const konf_buf_t *this)
  171. {
  172. return this->buf;
  173. }
  174. /*--------------------------------------------------------- */
  175. void * konf_buf__get_data(const konf_buf_t *this)
  176. {
  177. return this->data;
  178. }
  179. /*--------------------------------------------------------- */
  180. void konf_buf__set_data(konf_buf_t *this, void *data)
  181. {
  182. this->data = data;
  183. }
  184. /*---------------------------------------------------------
  185. * buftree functions
  186. *--------------------------------------------------------- */
  187. /*--------------------------------------------------------- */
  188. static int find_fd(const void *key, const void *data)
  189. {
  190. const int *fd = (const int *)key;
  191. const konf_buf_t *d = (const konf_buf_t *)data;
  192. return (*fd - d->fd);
  193. }
  194. /*--------------------------------------------------------- */
  195. konf_buf_t *konf_buftree_find(lub_list_t *this, int fd)
  196. {
  197. return lub_list_find(this, find_fd, &fd);
  198. }
  199. /*--------------------------------------------------------- */
  200. void konf_buftree_remove(lub_list_t *this, int fd)
  201. {
  202. lub_list_node_t *t;
  203. if ((t = lub_list_find_node(this, find_fd, &fd)) == NULL)
  204. return;
  205. konf_buf_delete((konf_buf_t *)lub_list_node__get_data(t));
  206. lub_list_del(this, t);
  207. lub_list_node_free(t);
  208. }