1/*-------------------------------------------------------------------------
2 *
3 * stringinfo.h
4 * Declarations/definitions for "StringInfo" functions.
5 *
6 * StringInfo provides an indefinitely-extensible string data type.
7 * It can be used to buffer either ordinary C strings (null-terminated text)
8 * or arbitrary binary data. All storage is allocated with palloc().
9 *
10 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
11 * Portions Copyright (c) 1994, Regents of the University of California
12 *
13 * src/include/lib/stringinfo.h
14 *
15 *-------------------------------------------------------------------------
16 */
17#ifndef STRINGINFO_H
18#define STRINGINFO_H
19
20/*-------------------------
21 * StringInfoData holds information about an extensible string.
22 * data is the current buffer for the string (allocated with palloc).
23 * len is the current string length. There is guaranteed to be
24 * a terminating '\0' at data[len], although this is not very
25 * useful when the string holds binary data rather than text.
26 * maxlen is the allocated size in bytes of 'data', i.e. the maximum
27 * string size (including the terminating '\0' char) that we can
28 * currently store in 'data' without having to reallocate
29 * more space. We must always have maxlen > len.
30 * cursor is initialized to zero by makeStringInfo or initStringInfo,
31 * but is not otherwise touched by the stringinfo.c routines.
32 * Some routines use it to scan through a StringInfo.
33 *-------------------------
34 */
35typedef struct StringInfoData
36{
37 char *data;
38 int len;
39 int maxlen;
40 int cursor;
41} StringInfoData;
42
43typedef StringInfoData *StringInfo;
44
45
46/*------------------------
47 * There are two ways to create a StringInfo object initially:
48 *
49 * StringInfo stringptr = makeStringInfo();
50 * Both the StringInfoData and the data buffer are palloc'd.
51 *
52 * StringInfoData string;
53 * initStringInfo(&string);
54 * The data buffer is palloc'd but the StringInfoData is just local.
55 * This is the easiest approach for a StringInfo object that will
56 * only live as long as the current routine.
57 *
58 * To destroy a StringInfo, pfree() the data buffer, and then pfree() the
59 * StringInfoData if it was palloc'd. There's no special support for this.
60 *
61 * NOTE: some routines build up a string using StringInfo, and then
62 * release the StringInfoData but return the data string itself to their
63 * caller. At that point the data string looks like a plain palloc'd
64 * string.
65 *-------------------------
66 */
67
68/*------------------------
69 * makeStringInfo
70 * Create an empty 'StringInfoData' & return a pointer to it.
71 */
72extern StringInfo makeStringInfo(void);
73
74/*------------------------
75 * initStringInfo
76 * Initialize a StringInfoData struct (with previously undefined contents)
77 * to describe an empty string.
78 */
79extern void initStringInfo(StringInfo str);
80
81/*------------------------
82 * resetStringInfo
83 * Clears the current content of the StringInfo, if any. The
84 * StringInfo remains valid.
85 */
86extern void resetStringInfo(StringInfo str);
87
88/*------------------------
89 * appendStringInfo
90 * Format text data under the control of fmt (an sprintf-style 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 */
95extern void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2, 3);
96
97/*------------------------
98 * appendStringInfoVA
99 * Attempt to format text data under the control of fmt (an sprintf-style
100 * format string) and append it to whatever is already in str. If successful
101 * return zero; if not (because there's not enough space), return an estimate
102 * of the space needed, without modifying str. Typically the caller should
103 * pass the return value to enlargeStringInfo() before trying again; see
104 * appendStringInfo for standard usage pattern.
105 */
106extern int appendStringInfoVA(StringInfo str, const char *fmt, va_list args) pg_attribute_printf(2, 0);
107
108/*------------------------
109 * appendStringInfoString
110 * Append a null-terminated string to str.
111 * Like appendStringInfo(str, "%s", s) but faster.
112 */
113extern void appendStringInfoString(StringInfo str, const char *s);
114
115/*------------------------
116 * appendStringInfoChar
117 * Append a single byte to str.
118 * Like appendStringInfo(str, "%c", ch) but much faster.
119 */
120extern void appendStringInfoChar(StringInfo str, char ch);
121
122/*------------------------
123 * appendStringInfoCharMacro
124 * As above, but a macro for even more speed where it matters.
125 * Caution: str argument will be evaluated multiple times.
126 */
127#define appendStringInfoCharMacro(str,ch) \
128 (((str)->len + 1 >= (str)->maxlen) ? \
129 appendStringInfoChar(str, ch) : \
130 (void)((str)->data[(str)->len] = (ch), (str)->data[++(str)->len] = '\0'))
131
132/*------------------------
133 * appendStringInfoSpaces
134 * Append a given number of spaces to str.
135 */
136extern void appendStringInfoSpaces(StringInfo str, int count);
137
138/*------------------------
139 * appendBinaryStringInfo
140 * Append arbitrary binary data to a StringInfo, allocating more space
141 * if necessary.
142 */
143extern void appendBinaryStringInfo(StringInfo str,
144 const char *data, int datalen);
145
146/*------------------------
147 * appendBinaryStringInfoNT
148 * Append arbitrary binary data to a StringInfo, allocating more space
149 * if necessary. Does not ensure a trailing null-byte exists.
150 */
151extern void appendBinaryStringInfoNT(StringInfo str,
152 const char *data, int datalen);
153
154/*------------------------
155 * enlargeStringInfo
156 * Make sure a StringInfo's buffer can hold at least 'needed' more bytes.
157 */
158extern void enlargeStringInfo(StringInfo str, int needed);
159
160#endif /* STRINGINFO_H */
161