stringinfo.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:4k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * stringinfo.c
  4.  *
  5.  * StringInfo provides an indefinitely-extensible string data type.
  6.  * It can be used to buffer either ordinary C strings (null-terminated text)
  7.  * or arbitrary binary data.  All storage is allocated with palloc().
  8.  *
  9.  * Copyright (c) 1994, Regents of the University of California
  10.  *
  11.  *   $Id: stringinfo.c,v 1.17 1999/05/26 12:55:14 momjian Exp $
  12.  *
  13.  *-------------------------------------------------------------------------
  14.  */
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include "postgres.h"
  18. #include "lib/stringinfo.h"
  19. #ifdef NOT_USED
  20. /*
  21.  * makeStringInfo
  22.  *
  23.  * Create an empty 'StringInfoData' & return a pointer to it.
  24.  */
  25. StringInfo
  26. makeStringInfo(void)
  27. {
  28. StringInfo res;
  29. res = (StringInfo) palloc(sizeof(StringInfoData));
  30. if (res == NULL)
  31. elog(ERROR, "makeStringInfo: Out of memory");
  32. initStringInfo(res);
  33. return res;
  34. }
  35. #endif
  36. /*
  37.  * initStringInfo
  38.  *
  39.  * Initialize a StringInfoData struct (with previously undefined contents)
  40.  * to describe an empty string.
  41.  */
  42. void
  43. initStringInfo(StringInfo str)
  44. {
  45. int size = 256; /* initial default buffer size */
  46. str->data = palloc(size);
  47. if (str->data == NULL)
  48. elog(ERROR,
  49.  "initStringInfo: Out of memory (%d bytes requested)", size);
  50. str->maxlen = size;
  51. str->len = 0;
  52. str->data[0] = '';
  53. }
  54. /*
  55.  * enlargeStringInfo
  56.  *
  57.  * Internal routine: make sure there is enough space for 'needed' more bytes
  58.  * ('needed' does not include the terminating null).
  59.  */
  60. static void
  61. enlargeStringInfo(StringInfo str, int needed)
  62. {
  63. int newlen;
  64. char    *newdata;
  65. needed += str->len + 1; /* total space required now */
  66. if (needed <= str->maxlen)
  67. return; /* got enough space already */
  68. /*
  69.  * We don't want to allocate just a little more space with each
  70.  * append; for efficiency, double the buffer size each time it
  71.  * overflows. Actually, we might need to more than double it if
  72.  * 'needed' is big...
  73.  */
  74. newlen = 2 * str->maxlen;
  75. while (needed > newlen)
  76. newlen = 2 * newlen;
  77. newdata = palloc(newlen);
  78. if (newdata == NULL)
  79. elog(ERROR,
  80. "enlargeStringInfo: Out of memory (%d bytes requested)", newlen);
  81. /* OK, transfer data into new buffer, and release old buffer */
  82. memcpy(newdata, str->data, str->len + 1);
  83. pfree(str->data);
  84. str->data = newdata;
  85. str->maxlen = newlen;
  86. }
  87. /*
  88.  * appendStringInfo
  89.  *
  90.  * Format text data under the control of fmt (an sprintf-like format string)
  91.  * and append it to whatever is already in str.  More space is allocated
  92.  * to str if necessary.  This is sort of like a combination of sprintf and
  93.  * strcat.
  94.  *
  95.  * CAUTION: the current implementation has a 1K limit on the amount of text
  96.  * generated in a single call (not on the total string length).
  97.  */
  98. void
  99. appendStringInfo(StringInfo str, const char *fmt,...)
  100. {
  101. va_list args;
  102. char buffer[1024];
  103. int buflen;
  104. Assert(str != NULL);
  105. va_start(args, fmt);
  106. buflen = vsnprintf(buffer, sizeof(buffer), fmt, args);
  107. va_end(args);
  108. /* Make more room if needed */
  109. enlargeStringInfo(str, buflen);
  110. /* OK, append the data, including the trailing null */
  111. memcpy(str->data + str->len, buffer, buflen + 1);
  112. str->len += buflen;
  113. }
  114. /*------------------------
  115.  * appendStringInfoChar
  116.  * Append a single byte to str.
  117.  * Like appendStringInfo(str, "%c", ch) but much faster.
  118.  */
  119. void
  120. appendStringInfoChar(StringInfo str, char ch)
  121. {
  122. Assert(str != NULL);
  123. /* Make more room if needed */
  124. enlargeStringInfo(str, 1);
  125. /* OK, append the character */
  126. str->data[str->len] = ch;
  127. str->len++;
  128. str->data[str->len] = '';
  129. }
  130. /*
  131.  * appendBinaryStringInfo
  132.  *
  133.  * Append arbitrary binary data to a StringInfo, allocating more space
  134.  * if necessary.
  135.  */
  136. void
  137. appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
  138. {
  139. Assert(str != NULL);
  140. /* Make more room if needed */
  141. enlargeStringInfo(str, datalen);
  142. /* OK, append the data */
  143. memcpy(str->data + str->len, data, datalen);
  144. str->len += datalen;
  145. /*
  146.  * Keep a trailing null in place, even though it's probably useless
  147.  * for binary data...
  148.  */
  149. str->data[str->len] = '';
  150. }