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-2024, 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  */
46 typedef struct StringInfoData
47 {
48  char *data;
49  int len;
50  int maxlen;
51  int cursor;
53 
55 
56 
57 /*------------------------
58  * There are four 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  * StringInfoData string;
64  * initStringInfo(&string);
65  * The data buffer is palloc'd but the StringInfoData is just local.
66  * This is the easiest approach for a StringInfo object that will
67  * only live as long as the current routine.
68  *
69  * StringInfoData string;
70  * initReadOnlyStringInfo(&string, existingbuf, len);
71  * The StringInfoData's data field is set to point directly to the
72  * existing buffer and the StringInfoData's len is set to the given len.
73  * The given buffer can point to memory that's not managed by palloc or
74  * is pointing partway through a palloc'd chunk. The maxlen field is set
75  * to 0. A read-only StringInfo cannot be appended to using any of the
76  * appendStringInfo functions or reset with resetStringInfo(). The given
77  * buffer can optionally omit the trailing NUL.
78  *
79  * StringInfoData string;
80  * initStringInfoFromString(&string, palloced_buf, len);
81  * The StringInfoData's data field is set to point directly to the given
82  * buffer and the StringInfoData's len is set to the given len. This
83  * method of initialization is useful when the buffer already exists.
84  * StringInfos initialized this way can be appended to using the
85  * appendStringInfo functions and reset with resetStringInfo(). The
86  * given buffer must be NUL-terminated. The palloc'd buffer is assumed
87  * to be len + 1 in size.
88  *
89  * To destroy a StringInfo, pfree() the data buffer, and then pfree() the
90  * StringInfoData if it was palloc'd. For StringInfos created with
91  * makeStringInfo(), destroyStringInfo() is provided for this purpose.
92  * However, if the StringInfo was initialized using initReadOnlyStringInfo()
93  * then the caller will need to consider if it is safe to pfree the data
94  * buffer.
95  *
96  * NOTE: some routines build up a string using StringInfo, and then
97  * release the StringInfoData but return the data string itself to their
98  * caller. At that point the data string looks like a plain palloc'd
99  * string.
100  *-------------------------
101  */
102 
103 /*------------------------
104  * makeStringInfo
105  * Create an empty 'StringInfoData' & return a pointer to it.
106  */
107 extern StringInfo makeStringInfo(void);
108 
109 /*------------------------
110  * initStringInfo
111  * Initialize a StringInfoData struct (with previously undefined contents)
112  * to describe an empty string.
113  */
114 extern void initStringInfo(StringInfo str);
115 
116 /*------------------------
117  * initReadOnlyStringInfo
118  * Initialize a StringInfoData struct from an existing string without copying
119  * the string. The caller is responsible for ensuring the given string
120  * remains valid as long as the StringInfoData does. Calls to this are used
121  * in performance critical locations where allocating a new buffer and copying
122  * would be too costly. Read-only StringInfoData's may not be appended to
123  * using any of the appendStringInfo functions or reset with
124  * resetStringInfo().
125  *
126  * 'data' does not need to point directly to a palloc'd chunk of memory and may
127  * omit the NUL termination character at data[len].
128  */
129 static inline void
131 {
132  str->data = data;
133  str->len = len;
134  str->maxlen = 0; /* read-only */
135  str->cursor = 0;
136 }
137 
138 /*------------------------
139  * initStringInfoFromString
140  * Initialize a StringInfoData struct from an existing string without copying
141  * the string. 'data' must be a valid palloc'd chunk of memory that can have
142  * repalloc() called should more space be required during a call to any of the
143  * appendStringInfo functions.
144  *
145  * 'data' must be NUL terminated at 'len' bytes.
146  */
147 static inline void
149 {
150  Assert(data[len] == '\0');
151 
152  str->data = data;
153  str->len = len;
154  str->maxlen = len + 1;
155  str->cursor = 0;
156 }
157 
158 /*------------------------
159  * resetStringInfo
160  * Clears the current content of the StringInfo, if any. The
161  * StringInfo remains valid.
162  */
163 extern void resetStringInfo(StringInfo str);
164 
165 /*------------------------
166  * appendStringInfo
167  * Format text data under the control of fmt (an sprintf-style format string)
168  * and append it to whatever is already in str. More space is allocated
169  * to str if necessary. This is sort of like a combination of sprintf and
170  * strcat.
171  */
172 extern void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2, 3);
173 
174 /*------------------------
175  * appendStringInfoVA
176  * Attempt to format text data under the control of fmt (an sprintf-style
177  * format string) and append it to whatever is already in str. If successful
178  * return zero; if not (because there's not enough space), return an estimate
179  * of the space needed, without modifying str. Typically the caller should
180  * pass the return value to enlargeStringInfo() before trying again; see
181  * appendStringInfo for standard usage pattern.
182  */
183 extern int appendStringInfoVA(StringInfo str, const char *fmt, va_list args) pg_attribute_printf(2, 0);
184 
185 /*------------------------
186  * appendStringInfoString
187  * Append a null-terminated string to str.
188  * Like appendStringInfo(str, "%s", s) but faster.
189  */
190 extern void appendStringInfoString(StringInfo str, const char *s);
191 
192 /*------------------------
193  * appendStringInfoChar
194  * Append a single byte to str.
195  * Like appendStringInfo(str, "%c", ch) but much faster.
196  */
197 extern void appendStringInfoChar(StringInfo str, char ch);
198 
199 /*------------------------
200  * appendStringInfoCharMacro
201  * As above, but a macro for even more speed where it matters.
202  * Caution: str argument will be evaluated multiple times.
203  */
204 #define appendStringInfoCharMacro(str,ch) \
205  (((str)->len + 1 >= (str)->maxlen) ? \
206  appendStringInfoChar(str, ch) : \
207  (void)((str)->data[(str)->len] = (ch), (str)->data[++(str)->len] = '\0'))
208 
209 /*------------------------
210  * appendStringInfoSpaces
211  * Append a given number of spaces to str.
212  */
213 extern void appendStringInfoSpaces(StringInfo str, int count);
214 
215 /*------------------------
216  * appendBinaryStringInfo
217  * Append arbitrary binary data to a StringInfo, allocating more space
218  * if necessary.
219  */
221  const void *data, int datalen);
222 
223 /*------------------------
224  * appendBinaryStringInfoNT
225  * Append arbitrary binary data to a StringInfo, allocating more space
226  * if necessary. Does not ensure a trailing null-byte exists.
227  */
229  const void *data, int datalen);
230 
231 /*------------------------
232  * enlargeStringInfo
233  * Make sure a StringInfo's buffer can hold at least 'needed' more bytes.
234  */
235 extern void enlargeStringInfo(StringInfo str, int needed);
236 
237 /*------------------------
238  * destroyStringInfo
239  * Frees a StringInfo and its buffer (opposite of makeStringInfo()).
240  */
241 extern void destroyStringInfo(StringInfo str);
242 
243 #endif /* STRINGINFO_H */
#define Assert(condition)
Definition: c.h:858
#define pg_attribute_printf(f, a)
Definition: c.h:191
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:148
void destroyStringInfo(StringInfo str)
Definition: stringinfo.c:361
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
struct StringInfoData StringInfoData
StringInfoData * StringInfo
Definition: stringinfo.h:54
void int void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:78
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:289
void appendBinaryStringInfoNT(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:259
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:233
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:130
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:212
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59