buf.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. * PRIVATE META FUNCTIONS
  18. *--------------------------------------------------------- */
  19. int konf_buf_bt_compare(const void *clientnode, const void *clientkey)
  20. {
  21. const konf_buf_t *this = clientnode;
  22. int keyfd;
  23. memcpy(&keyfd, clientkey, sizeof(keyfd));
  24. return (this->fd - keyfd);
  25. }
  26. /*-------------------------------------------------------- */
  27. static void konf_buf_key(lub_bintree_key_t * key,
  28. int fd)
  29. {
  30. memcpy(key, &fd, sizeof(fd));
  31. }
  32. /*-------------------------------------------------------- */
  33. void konf_buf_bt_getkey(const void *clientnode, lub_bintree_key_t * key)
  34. {
  35. const konf_buf_t *this = clientnode;
  36. konf_buf_key(key, this->fd);
  37. }
  38. /*---------------------------------------------------------
  39. * PRIVATE METHODS
  40. *--------------------------------------------------------- */
  41. static void
  42. konf_buf_init(konf_buf_t * this, int fd)
  43. {
  44. this->fd = fd;
  45. this->buf = malloc(KONF_BUF_CHUNK);
  46. this->size = KONF_BUF_CHUNK;
  47. this->pos = 0;
  48. this->rpos = 0;
  49. this->data = NULL;
  50. /* Be a good binary tree citizen */
  51. lub_bintree_node_init(&this->bt_node);
  52. }
  53. /*--------------------------------------------------------- */
  54. static void konf_buf_fini(konf_buf_t * this)
  55. {
  56. free(this->buf);
  57. }
  58. /*---------------------------------------------------------
  59. * PUBLIC META FUNCTIONS
  60. *--------------------------------------------------------- */
  61. size_t konf_buf_bt_offset(void)
  62. {
  63. return offsetof(konf_buf_t, bt_node);
  64. }
  65. /*--------------------------------------------------------- */
  66. konf_buf_t *konf_buf_new(int fd)
  67. {
  68. konf_buf_t *this = malloc(sizeof(konf_buf_t));
  69. if (this)
  70. konf_buf_init(this, fd);
  71. return this;
  72. }
  73. /*---------------------------------------------------------
  74. * PUBLIC METHODS
  75. *--------------------------------------------------------- */
  76. void konf_buf_delete(konf_buf_t * this)
  77. {
  78. konf_buf_fini(this);
  79. free(this);
  80. }
  81. /*--------------------------------------------------------- */
  82. static int konf_buf_realloc(konf_buf_t *this, int addsize)
  83. {
  84. int chunk = KONF_BUF_CHUNK;
  85. char *tmpbuf;
  86. if (addsize > chunk)
  87. chunk = addsize;
  88. if ((this->size - this->pos) < chunk) {
  89. tmpbuf = realloc(this->buf, this->size + chunk);
  90. this->buf = tmpbuf;
  91. this->size += chunk;
  92. }
  93. return this->size;
  94. }
  95. /*--------------------------------------------------------- */
  96. int konf_buf_add(konf_buf_t *this, void *str, size_t len)
  97. {
  98. char *buffer;
  99. konf_buf_realloc(this, len);
  100. buffer = this->buf + this->pos;
  101. memcpy(buffer, str, len);
  102. this->pos += len;
  103. return len;
  104. }
  105. /*--------------------------------------------------------- */
  106. int konf_buf_read(konf_buf_t *this)
  107. {
  108. char *buffer;
  109. int buffer_size;
  110. int nbytes;
  111. konf_buf_realloc(this, 0);
  112. buffer_size = this->size - this->pos;
  113. buffer = this->buf + this->pos;
  114. nbytes = read(this->fd, buffer, buffer_size);
  115. if (nbytes > 0)
  116. this->pos += nbytes;
  117. return nbytes;
  118. }
  119. /*--------------------------------------------------------- */
  120. char * konf_buf_string(char *buf, int len)
  121. {
  122. unsigned i;
  123. char *str;
  124. for (i = 0; i < len; i++) {
  125. if (('\0' == buf[i]) ||
  126. ('\n' == buf[i]))
  127. break;
  128. }
  129. if (i >= len)
  130. return NULL;
  131. str = malloc(i + 1);
  132. memcpy(str, buf, i + 1);
  133. str[i] = '\0';
  134. return str;
  135. }
  136. /*--------------------------------------------------------- */
  137. char * konf_buf_parse(konf_buf_t *this)
  138. {
  139. char * str = NULL;
  140. /* Search the buffer for the string */
  141. str = konf_buf_string(this->buf, this->pos);
  142. /* Remove parsed string from the buffer */
  143. if (str) {
  144. int len = strlen(str) + 1;
  145. memmove(this->buf, &this->buf[len], this->pos - len);
  146. this->pos -= len;
  147. if (this->rpos >= len)
  148. this->rpos -= len;
  149. else
  150. this->rpos = 0;
  151. }
  152. /* Make buffer shorter */
  153. if ((this->size - this->pos) > (2 * KONF_BUF_CHUNK)) {
  154. char *tmpbuf;
  155. tmpbuf = realloc(this->buf, this->size - KONF_BUF_CHUNK);
  156. this->buf = tmpbuf;
  157. this->size -= KONF_BUF_CHUNK;
  158. }
  159. return str;
  160. }
  161. /*--------------------------------------------------------- */
  162. char * konf_buf_preparse(konf_buf_t *this)
  163. {
  164. char * str = NULL;
  165. str = konf_buf_string(this->buf + this->rpos, this->pos - this->rpos);
  166. if (str)
  167. this->rpos += (strlen(str) + 1);
  168. return str;
  169. }
  170. /*--------------------------------------------------------- */
  171. int konf_buf_lseek(konf_buf_t *this, int newpos)
  172. {
  173. if (newpos > this->pos)
  174. return -1;
  175. this->rpos = newpos;
  176. return newpos;
  177. }
  178. /*--------------------------------------------------------- */
  179. int konf_buf__get_fd(const konf_buf_t * this)
  180. {
  181. return this->fd;
  182. }
  183. /*--------------------------------------------------------- */
  184. int konf_buf__get_len(const konf_buf_t *this)
  185. {
  186. return this->pos;
  187. }
  188. /*--------------------------------------------------------- */
  189. char * konf_buf__dup_line(const konf_buf_t *this)
  190. {
  191. char *str;
  192. str = malloc(this->pos + 1);
  193. memcpy(str, this->buf, this->pos);
  194. str[this->pos] = '\0';
  195. return str;
  196. }
  197. /*--------------------------------------------------------- */
  198. void * konf_buf__get_data(const konf_buf_t *this)
  199. {
  200. return this->data;
  201. }
  202. /*--------------------------------------------------------- */
  203. void konf_buf__set_data(konf_buf_t *this, void *data)
  204. {
  205. this->data = data;
  206. }
  207. /*---------------------------------------------------------
  208. * buftree functions
  209. *--------------------------------------------------------- */
  210. /*--------------------------------------------------------- */
  211. konf_buf_t *konf_buftree_find(lub_bintree_t * this,
  212. int fd)
  213. {
  214. lub_bintree_key_t key;
  215. konf_buf_key(&key, fd);
  216. return lub_bintree_find(this, &key);
  217. }
  218. /*--------------------------------------------------------- */
  219. void konf_buftree_remove(lub_bintree_t * this,
  220. int fd)
  221. {
  222. konf_buf_t *tbuf;
  223. if ((tbuf = konf_buftree_find(this, fd)) == NULL)
  224. return;
  225. lub_bintree_remove(this, tbuf);
  226. konf_buf_delete(tbuf);
  227. }
  228. /*--------------------------------------------------------- */
  229. int konf_buftree_read(lub_bintree_t * this, int fd)
  230. {
  231. konf_buf_t *buf;
  232. buf = konf_buftree_find(this, fd);
  233. if (!buf)
  234. return -1;
  235. return konf_buf_read(buf);
  236. }
  237. /*--------------------------------------------------------- */
  238. char * konf_buftree_parse(lub_bintree_t * this,
  239. int fd)
  240. {
  241. konf_buf_t *buf;
  242. buf = konf_buftree_find(this, fd);
  243. if (!buf)
  244. return NULL;
  245. return konf_buf_parse(buf);
  246. }