dstrbuf.c
上传用户:knt0001
上传日期:2022-01-28
资源大小:264k
文件大小:6k
源码类别:

Email客户端

开发平台:

C/C++

  1. #include <string.h>
  2. #include <assert.h>
  3. #include <unistd.h>
  4. #include "dstrbuf.h"
  5. #include "dutil.h"
  6. /*
  7.  * Create a new dstrbuf.
  8.  *
  9.  * Params
  10.  * size - The initial size of the dstrbuf
  11.  * maxsize - The maximum size the dstrbuf can grow to (0 for infinite)
  12.  *
  13.  * Return
  14.  * A new dstrbuf
  15.  */
  16. dstrbuf *
  17. dsbNew(size_t size)
  18. {
  19. dstrbuf *ret = xmalloc(sizeof(struct __dstrbuf));
  20. ret->str = xmalloc(size + 1);
  21. ret->size = size;
  22. ret->len = 0;
  23. return ret;
  24. }
  25. /*
  26.  * Resize the string
  27.  *
  28.  * Params
  29.  * dsb - The dstrbuf to grow
  30.  * newsize - The new size of the string
  31.  */
  32. void
  33. dsbResize(dstrbuf *dsb, size_t newsize)
  34. {
  35. assert(dsb != NULL);
  36. dsb->str = xrealloc(dsb->str, newsize + 1);
  37. dsb->str[newsize] = '';
  38. dsb->size = newsize;
  39. }
  40. /*
  41.  * Destroy a dstrbuf (Free memory and NULL)
  42.  *
  43.  * Params
  44.  * dsb - The dstrbuf to destroy
  45.  */
  46. void 
  47. dsbDestroy(dstrbuf *dsb)
  48. {
  49. if (dsb) {
  50. xfree(dsb->str);
  51. xfree(dsb);
  52. }
  53. }
  54. /*
  55.  * Clear a dstrbuf (zero buffer memory)
  56.  *
  57.  * Params
  58.  * dsb - dstrbuf to clear
  59.  */
  60. void 
  61. dsbClear(dstrbuf *dsb)
  62. {
  63. assert(dsb != NULL);
  64. memset(dsb->str, '', dsb->size);
  65. dsb->len = 0;
  66. }
  67. /*
  68.  * Copy a char buffer into a dstrbuf
  69.  *
  70.  * Params
  71.  * dsb - Destination dstrbuf
  72.  * buf - Buffer to copy from
  73.  * size - total bytes to copy
  74.  *
  75.  * Return
  76.  * Total size that was copied. If size is greater than
  77.  * maxsize, then only maxsize will be copied.
  78.  */
  79. size_t 
  80. dsbCopy(dstrbuf *dsb, const char *buf)
  81. {
  82. size_t length = strlen(buf);
  83. assert(dsb != NULL);
  84. if (length > dsb->size) {
  85. dsbResize(dsb, length);
  86. }
  87. memcpy(dsb->str, buf, length);
  88. dsb->len = length;
  89. dsb->str[dsb->len] = '';
  90. return length;
  91. }
  92. /*
  93.  * Copy a char buffer into a dstrbuf up to size bytes
  94.  *
  95.  * Params
  96.  * dsb - Destination dstrbuf
  97.  * buf - Buffer to copy from
  98.  * size - total bytes to copy
  99.  *
  100.  * Return
  101.  * Total size that was copied. If size is greater than
  102.  * maxsize, then only maxsize will be copied.
  103.  */
  104. size_t 
  105. dsbnCopy(dstrbuf *dsb, const char *buf, size_t size)
  106. {
  107. size_t len = strlen(buf);
  108. assert(dsb != NULL);
  109. if (len < size) {
  110. size = len;
  111. }
  112. if (size > dsb->size) {
  113. dsbResize(dsb, size);
  114. }
  115. memcpy(dsb->str, buf, size);
  116. dsb->len = size;
  117. dsb->str[dsb->len] = '';
  118. return size;
  119. }
  120. /*
  121.  * Concat data onto the end of a dstrbuf buffer
  122.  *
  123.  * Params
  124.  * dest - The dstrbuf to concat data to
  125.  * src - The char buf to copy from
  126.  *
  127.  * Return
  128.  * total chars (bytes) copied
  129.  */
  130. size_t 
  131. dsbCat(dstrbuf *dest, const char *src)
  132. {
  133. size_t length = strlen(src);
  134. size_t totalSize = 0;
  135. assert(dest != NULL);
  136. totalSize = dest->len + length;
  137. if (totalSize > dest->size) {
  138. dsbResize(dest, totalSize);
  139. }
  140. memcpy(dest->str + dest->len, src, length);
  141. dest->len += length;
  142. dest->str[dest->len] = '';
  143. return length;
  144. }
  145. /*
  146.  * Concat data onto the end of a dstrbuf buffer up to size bytes
  147.  *
  148.  * Params
  149.  * dest - The dstrbuf to concat data to
  150.  * src - The char buf to copy from
  151.  * size - total bytes to copy
  152.  *
  153.  * Return
  154.  * total chars (bytes) copied
  155.  */
  156. size_t 
  157. dsbnCat(dstrbuf *dest, const char *src, size_t size)
  158. {
  159. size_t totalSize = 0;
  160. size_t length = strlen(src);
  161. assert(dest != NULL);
  162. if (length < size) {
  163. size = length;
  164. }
  165. totalSize = dest->len + size;
  166. if (totalSize > dest->size) {
  167. dsbResize(dest, totalSize);
  168. }
  169. memcpy(dest->str + dest->len, src, size);
  170. dest->len = totalSize;
  171. dest->str[dest->len] = '';
  172. return size;
  173. }
  174. /*
  175.  * Appends a character to the buffer.
  176.  *
  177.  * Params
  178.  * dsb - The dsb to concat to
  179.  * ch  - The character to concat
  180.  */
  181. void
  182. dsbCatChar(dstrbuf *dest, const u_char ch)
  183. {
  184. if (dest->len+sizeof(u_char) >= dest->size) {
  185. dsbResize(dest, dest->len+sizeof(u_char));
  186. }
  187. dest->str[dest->len] = ch;
  188. dest->len++;
  189. dest->str[dest->len] = '';
  190. }
  191. /*
  192.  * Similar to sprintf but appends to the end of the string.
  193.  *
  194.  * Params
  195.  * dsb - The dsb to concat to
  196.  * fmt - The format of the string
  197.  * ... - arguments
  198.  *
  199.  * Return
  200.  * total number of bytes written, -1 if vsnprintf error
  201.  */
  202. int 
  203. dsbPrintf(dstrbuf *dsb, const char *fmt, ...)
  204. {
  205. va_list ap;
  206. int actualLen=0, size;
  207. assert(dsb != NULL);
  208. while (true) {
  209. va_start(ap, fmt);
  210. size = dsb->size - dsb->len;
  211. actualLen = vsnprintf(dsb->str+dsb->len, size, fmt, ap);
  212. va_end(ap);
  213. // Check for failure to write
  214. if (actualLen > -1 && actualLen < size) {
  215. // String written properly.
  216. break;
  217. } else if (actualLen > -1) {
  218. size = dsb->size + (actualLen - size);
  219. dsbResize(dsb, size + 1);
  220. } else {
  221. dsbResize(dsb, dsb->size * 2);
  222. }
  223. }
  224. dsb->len += actualLen;
  225. return actualLen;
  226. }
  227. /*
  228.  * Reads a line from a FILE
  229.  *
  230.  * Params
  231.  * dsb - The dstrbuf to store the data into
  232.  * file - a FILE to read the data from
  233.  *
  234.  * Returns
  235.  * number of bytes read.
  236.  */
  237. size_t
  238. dsbReadline(dstrbuf *dsb, FILE *file)
  239. {
  240. int ch=0;
  241. size_t totalLen=0;
  242. assert(dsb != NULL);
  243. dsbClear(dsb);
  244. while ((ch = fgetc(file)) != EOF) {
  245. totalLen++;
  246. dsbCatChar(dsb, (char)ch);
  247. if (ch == 'n') {
  248. break;
  249. }
  250. }
  251. return totalLen;
  252. }
  253. /*
  254.  * Reads a chunk of data from a FILE
  255.  *
  256.  * Params
  257.  * dsb - The dstrbuf to store the data into
  258.  * bytes - number of bytes to read.
  259.  * file - a FILE to read the data from
  260.  *
  261.  * Returns
  262.  * number of bytes read.
  263.  */
  264. size_t
  265. dsbFread(dstrbuf *dsb, size_t bytes, FILE *file)
  266. {
  267. size_t actualLen = 0;
  268. assert(dsb != NULL);
  269. if (bytes > dsb->size) {
  270. dsbResize(dsb, bytes);
  271. }
  272. actualLen = fread(dsb->str, 1, bytes, file);
  273. dsb->len = actualLen;
  274. dsb->str[dsb->len] = '';
  275. return actualLen;
  276. }
  277. /*
  278.  * Reads data from a file
  279.  *
  280.  * Params
  281.  * dsb - The dstrbuf to store the data in
  282.  * size - The size of the data to read
  283.  * fd - A standard unix file descriptor
  284.  *
  285.  * Return
  286.  * Total bytes read
  287.  */
  288. ssize_t
  289. dsbRead(dstrbuf *dsb, size_t size, int fd)
  290. {
  291. ssize_t actualLen = 0;
  292. assert(dsb != NULL);
  293. if (size > dsb->size) {
  294. dsbResize(dsb, size);
  295. }
  296. actualLen = read(fd, dsb->str, size);
  297. dsb->len = actualLen;
  298. dsb->str[dsb->len] = '';
  299. return actualLen;
  300. }