buf.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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 keysock;
  23. memcpy(&keysock, clientkey, sizeof(keysock));
  24. return (this->sock - keysock);
  25. }
  26. /*-------------------------------------------------------- */
  27. static void konf_buf_key(lub_bintree_key_t * key,
  28. int sock)
  29. {
  30. memcpy(key, &sock, sizeof(sock));
  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->sock);
  37. }
  38. /*---------------------------------------------------------
  39. * PRIVATE METHODS
  40. *--------------------------------------------------------- */
  41. static void
  42. konf_buf_init(konf_buf_t * this, int sock)
  43. {
  44. this->sock = sock;
  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 sock)
  66. {
  67. konf_buf_t *this = malloc(sizeof(konf_buf_t));
  68. if (this) {
  69. konf_buf_init(this, sock);
  70. }
  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->sock, 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_sock(const konf_buf_t * this)
  180. {
  181. return this->sock;
  182. }
  183. /*--------------------------------------------------------- */
  184. int konf_buf__get_len(const konf_buf_t *this)
  185. {
  186. return this->pos;
  187. }
  188. /*---------------------------------------------------------
  189. * buftree functions
  190. *--------------------------------------------------------- */
  191. /*--------------------------------------------------------- */
  192. konf_buf_t *konf_buftree_find(lub_bintree_t * this,
  193. int sock)
  194. {
  195. lub_bintree_key_t key;
  196. konf_buf_key(&key, sock);
  197. return lub_bintree_find(this, &key);
  198. }
  199. /*--------------------------------------------------------- */
  200. void konf_buftree_remove(lub_bintree_t * this,
  201. int sock)
  202. {
  203. konf_buf_t *tbuf;
  204. if ((tbuf = konf_buftree_find(this, sock)) == NULL)
  205. return;
  206. lub_bintree_remove(this, tbuf);
  207. konf_buf_delete(tbuf);
  208. }
  209. /*--------------------------------------------------------- */
  210. int konf_buftree_read(lub_bintree_t * this, int sock)
  211. {
  212. konf_buf_t *buf;
  213. buf = konf_buftree_find(this, sock);
  214. if (!buf)
  215. return -1;
  216. return konf_buf_read(buf);
  217. }
  218. /*--------------------------------------------------------- */
  219. char * konf_buftree_parse(lub_bintree_t * this,
  220. int sock)
  221. {
  222. konf_buf_t *buf;
  223. buf = konf_buftree_find(this, sock);
  224. if (!buf)
  225. return NULL;
  226. return konf_buf_parse(buf);
  227. }