PostgreSQL Source Code git master
stringinfo.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * stringinfo.h
4 * Declarations/definitions for "StringInfo" functions.
5 *
6 * StringInfo provides an extensible string data type (currently limited to a
7 * length of 1GB). It can be used to buffer either ordinary C strings
8 * (null-terminated text) or arbitrary binary data. All storage is allocated
9 * with palloc() (falling back to malloc in frontend code).
10 *
11 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
13 *
14 * src/include/lib/stringinfo.h
15 *
16 *-------------------------------------------------------------------------
17 */
18#ifndef STRINGINFO_H
19#define STRINGINFO_H
20
21/*-------------------------
22 * StringInfoData holds information about an extensible string.
23 * data is the current buffer for the string.
24 * len is the current string length. Except in the case of read-only
25 * strings described below, there is guaranteed to be a
26 * terminating '\0' at data[len].
27 * maxlen is the allocated size in bytes of 'data', i.e. the maximum
28 * string size (including the terminating '\0' char) that we can
29 * currently store in 'data' without having to reallocate
30 * more space. We must always have maxlen > len, except
31 * in the read-only case described below.
32 * cursor is initialized to zero by makeStringInfo, initStringInfo,
33 * initReadOnlyStringInfo and initStringInfoFromString but is not
34 * otherwise touched by the stringinfo.c routines. Some routines
35 * use it to scan through a StringInfo.
36 *
37 * As a special case, a StringInfoData can be initialized with a read-only
38 * string buffer. In this case "data" does not necessarily point at a
39 * palloc'd chunk, and management of the buffer storage is the caller's
40 * responsibility. maxlen is set to zero to indicate that this is the case.
41 * Read-only StringInfoDatas cannot be appended to or reset.
42 * Also, it is caller's option whether a read-only string buffer has a
43 * terminating '\0' or not. This depends on the intended usage.
44 *-------------------------
45 */
46typedef struct StringInfoData
47{
48 char *data;
49 int len;
50 int maxlen;
51 int cursor;
53
55
56
57/*------------------------
58 * There are six ways to create a StringInfo object initially:
59 *
60 * StringInfo stringptr = makeStringInfo();
61 * Both the StringInfoData and the data buffer are palloc'd.
62 *
63 * StringInfo stringptr = makeStringInfoExt(initsize);
64 * Same as makeStringInfo except the data buffer is allocated
65 * with size 'initsize'.
66 *
67 * StringInfoData string;
68 * initStringInfo(&string);
69 * The data buffer is palloc'd but the StringInfoData is just local.
70 * This is the easiest approach for a StringInfo object that will
71 * only live as long as the current routine.
72 *
73 * StringInfoData string;
74 * initStringInfoExt(&string, initsize);
75 * Same as initStringInfo except the data buffer is allocated
76 * with size 'initsize'.
77 *
78 * StringInfoData string;
79 * initReadOnlyStringInfo(&string, existingbuf, len);
80 * The StringInfoData's data field is set to point directly to the
81 * existing buffer and the StringInfoData's len is set to the given len.
82 * The given buffer can point to memory that's not managed by palloc or
83 * is pointing partway through a palloc'd chunk. The maxlen field is set
84 * to 0. A read-only StringInfo cannot be appended to using any of the
85 * appendStringInfo functions or reset with resetStringInfo(). The given
86 * buffer can optionally omit the trailing NUL.
87 *
88 * StringInfoData string;
89 * initStringInfoFromString(&string, palloced_buf, len);
90 * The StringInfoData's data field is set to point directly to the given
91 * buffer and the StringInfoData's len is set to the given len. This
92 * method of initialization is useful when the buffer already exists.
93 * StringInfos initialized this way can be appended to using the
94 * appendStringInfo functions and reset with resetStringInfo(). The
95 * given buffer must be NUL-terminated. The palloc'd buffer is assumed
96 * to be len + 1 in size.
97 *
98 * To destroy a StringInfo, pfree() the data buffer, and then pfree() the
99 * StringInfoData if it was palloc'd. For StringInfos created with
100 * makeStringInfo(), destroyStringInfo() is provided for this purpose.
101 * However, if the StringInfo was initialized using initReadOnlyStringInfo()
102 * then the caller will need to consider if it is safe to pfree the data
103 * buffer.
104 *
105 * NOTE: some routines build up a string using StringInfo, and then
106 * release the StringInfoData but return the data string itself to their
107 * caller. At that point the data string looks like a plain palloc'd
108 * string.
109 *-------------------------
110 */
111
112#define STRINGINFO_DEFAULT_SIZE 1024 /* default initial allocation size */
113
114/*------------------------
115 * makeStringInfo
116 * Create an empty 'StringInfoData' & return a pointer to it.
117 */
118extern StringInfo makeStringInfo(void);
119
120/*------------------------
121 * makeStringInfoExt
122 * Create an empty 'StringInfoData' & return a pointer to it.
123 * The data buffer is allocated with size 'initsize'.
124 * The valid range for 'initsize' is 1 to MaxAllocSize.
125 */
126extern StringInfo makeStringInfoExt(int initsize);
127
128/*------------------------
129 * initStringInfo
130 * Initialize a StringInfoData struct (with previously undefined contents)
131 * to describe an empty string.
132 */
133extern void initStringInfo(StringInfo str);
134
135/*------------------------
136 * initStringInfoExt
137 * Initialize a StringInfoData struct (with previously undefined contents) to
138 * describe an empty string. The data buffer is allocated with size
139 * 'initsize'. The valid range for 'initsize' is 1 to MaxAllocSize.
140 */
141extern void initStringInfoExt(StringInfo str, int initsize);
142
143/*------------------------
144 * initReadOnlyStringInfo
145 * Initialize a StringInfoData struct from an existing string without copying
146 * the string. The caller is responsible for ensuring the given string
147 * remains valid as long as the StringInfoData does. Calls to this are used
148 * in performance critical locations where allocating a new buffer and copying
149 * would be too costly. Read-only StringInfoData's may not be appended to
150 * using any of the appendStringInfo functions or reset with
151 * resetStringInfo().
152 *
153 * 'data' does not need to point directly to a palloc'd chunk of memory and may
154 * omit the NUL termination character at data[len].
155 */
156static inline void
158{
159 str->data = data;
160 str->len = len;
161 str->maxlen = 0; /* read-only */
162 str->cursor = 0;
163}
164
165/*------------------------
166 * initStringInfoFromString
167 * Initialize a StringInfoData struct from an existing string without copying
168 * the string. 'data' must be a valid palloc'd chunk of memory that can have
169 * repalloc() called should more space be required during a call to any of the
170 * appendStringInfo functions.
171 *
172 * 'data' must be NUL terminated at 'len' bytes.
173 */
174static inline void
176{
177 Assert(data[len] == '\0');
178
179 str->data = data;
180 str->len = len;
181 str->maxlen = len + 1;
182 str->cursor = 0;
183}
184
185/*------------------------
186 * resetStringInfo
187 * Clears the current content of the StringInfo, if any. The
188 * StringInfo remains valid.
189 */
190extern void resetStringInfo(StringInfo str);
191
192/*------------------------
193 * appendStringInfo
194 * Format text data under the control of fmt (an sprintf-style format string)
195 * and append it to whatever is already in str. More space is allocated
196 * to str if necessary. This is sort of like a combination of sprintf and
197 * strcat.
198 */
199extern void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2, 3);
200
201/*------------------------
202 * appendStringInfoVA
203 * Attempt to format text data under the control of fmt (an sprintf-style
204 * format string) and append it to whatever is already in str. If successful
205 * return zero; if not (because there's not enough space), return an estimate
206 * of the space needed, without modifying str. Typically the caller should
207 * pass the return value to enlargeStringInfo() before trying again; see
208 * appendStringInfo for standard usage pattern.
209 */
210extern int appendStringInfoVA(StringInfo str, const char *fmt, va_list args) pg_attribute_printf(2, 0);
211
212/*------------------------
213 * appendStringInfoString
214 * Append a null-terminated string to str.
215 * Like appendStringInfo(str, "%s", s) but faster.
216 */
217extern void appendStringInfoString(StringInfo str, const char *s);
218
219/*------------------------
220 * appendStringInfoChar
221 * Append a single byte to str.
222 * Like appendStringInfo(str, "%c", ch) but much faster.
223 */
224extern void appendStringInfoChar(StringInfo str, char ch);
225
226/*------------------------
227 * appendStringInfoCharMacro
228 * As above, but a macro for even more speed where it matters.
229 * Caution: str argument will be evaluated multiple times.
230 */
231#define appendStringInfoCharMacro(str,ch) \
232 (((str)->len + 1 >= (str)->maxlen) ? \
233 appendStringInfoChar(str, ch) : \
234 (void)((str)->data[(str)->len] = (ch), (str)->data[++(str)->len] = '\0'))
235
236/*------------------------
237 * appendStringInfoSpaces
238 * Append a given number of spaces to str.
239 */
240extern void appendStringInfoSpaces(StringInfo str, int count);
241
242/*------------------------
243 * appendBinaryStringInfo
244 * Append arbitrary binary data to a StringInfo, allocating more space
245 * if necessary.
246 */
248 const void *data, int datalen);
249
250/*------------------------
251 * appendBinaryStringInfoNT
252 * Append arbitrary binary data to a StringInfo, allocating more space
253 * if necessary. Does not ensure a trailing null-byte exists.
254 */
256 const void *data, int datalen);
257
258/*------------------------
259 * enlargeStringInfo
260 * Make sure a StringInfo's buffer can hold at least 'needed' more bytes.
261 */
262extern void enlargeStringInfo(StringInfo str, int needed);
263
264/*------------------------
265 * destroyStringInfo
266 * Frees a StringInfo and its buffer (opposite of makeStringInfo()).
267 */
268extern void destroyStringInfo(StringInfo str);
269
270#endif /* STRINGINFO_H */
#define Assert(condition)
Definition: c.h:815
#define pg_attribute_printf(f, a)
Definition: c.h:213
const char * str
static void const char * fmt
const void size_t len
const void * data
void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2
static void initStringInfoFromString(StringInfo str, char *data, int len)
Definition: stringinfo.h:175
void destroyStringInfo(StringInfo str)
Definition: stringinfo.c:409
StringInfo makeStringInfo(void)
Definition: stringinfo.c:72
struct StringInfoData StringInfoData
StringInfoData * StringInfo
Definition: stringinfo.h:54
void int void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:126
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:337
StringInfo makeStringInfoExt(int initsize)
Definition: stringinfo.c:85
void appendBinaryStringInfoNT(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:307
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281
void int appendStringInfoVA(StringInfo str, const char *fmt, va_list args) pg_attribute_printf(2
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition: stringinfo.h:157
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:260
void initStringInfoExt(StringInfo str, int initsize)
Definition: stringinfo.c:111
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97