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 | */ |
35 | typedef struct StringInfoData |
36 | { |
37 | char *data; |
38 | int len; |
39 | int maxlen; |
40 | int cursor; |
41 | } StringInfoData; |
42 | |
43 | typedef 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 | */ |
72 | extern StringInfo makeStringInfo(void); |
73 | |
74 | /*------------------------ |
75 | * initStringInfo |
76 | * Initialize a StringInfoData struct (with previously undefined contents) |
77 | * to describe an empty string. |
78 | */ |
79 | extern void initStringInfo(StringInfo str); |
80 | |
81 | /*------------------------ |
82 | * resetStringInfo |
83 | * Clears the current content of the StringInfo, if any. The |
84 | * StringInfo remains valid. |
85 | */ |
86 | extern 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 | */ |
95 | extern 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 | */ |
106 | extern 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 | */ |
113 | extern 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 | */ |
120 | extern 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 | */ |
136 | extern 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 | */ |
143 | extern 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 | */ |
151 | extern 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 | */ |
158 | extern void enlargeStringInfo(StringInfo str, int needed); |
159 | |
160 | #endif /* STRINGINFO_H */ |
161 | |