buf.c 6.1 KB

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