PostgreSQL Source Code  git master
pqexpbuffer.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pqexpbuffer.h
4  * Declarations/definitions for "PQExpBuffer" functions.
5  *
6  * PQExpBuffer 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 malloc().
9  *
10  * This module is essentially the same as the backend's StringInfo data type,
11  * but it is intended for use in frontend libpq and client applications.
12  * Thus, it does not rely on palloc() nor elog().
13  *
14  * It does rely on vsnprintf(); if configure finds that libc doesn't provide
15  * a usable vsnprintf(), then a copy of our own implementation of it will
16  * be linked into libpq.
17  *
18  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
19  * Portions Copyright (c) 1994, Regents of the University of California
20  *
21  * src/interfaces/libpq/pqexpbuffer.h
22  *
23  *-------------------------------------------------------------------------
24  */
25 #ifndef PQEXPBUFFER_H
26 #define PQEXPBUFFER_H
27 
28 /*-------------------------
29  * PQExpBufferData holds information about an extensible string.
30  * data is the current buffer for the string (allocated with malloc).
31  * len is the current string length. There is guaranteed to be
32  * a terminating '\0' at data[len], although this is not very
33  * useful when the string holds binary data rather than text.
34  * maxlen is the allocated size in bytes of 'data', i.e. the maximum
35  * string size (including the terminating '\0' char) that we can
36  * currently store in 'data' without having to reallocate
37  * more space. We must always have maxlen > len.
38  *
39  * An exception occurs if we failed to allocate enough memory for the string
40  * buffer. In that case data points to a statically allocated empty string,
41  * and len = maxlen = 0.
42  *-------------------------
43  */
44 typedef struct PQExpBufferData
45 {
46  char *data;
47  size_t len;
48  size_t maxlen;
50 
52 
53 /*------------------------
54  * Test for a broken (out of memory) PQExpBuffer.
55  * When a buffer is "broken", all operations except resetting or deleting it
56  * are no-ops.
57  *------------------------
58  */
59 #define PQExpBufferBroken(str) \
60  ((str) == NULL || (str)->maxlen == 0)
61 
62 /*------------------------
63  * Same, but for use when using a static or local PQExpBufferData struct.
64  * For that, a null-pointer test is useless and may draw compiler warnings.
65  *------------------------
66  */
67 #define PQExpBufferDataBroken(buf) \
68  ((buf).maxlen == 0)
69 
70 /*------------------------
71  * Initial size of the data buffer in a PQExpBuffer.
72  * NB: this must be large enough to hold error messages that might
73  * be returned by PQrequestCancel().
74  *------------------------
75  */
76 #define INITIAL_EXPBUFFER_SIZE 256
77 
78 /*------------------------
79  * There are two ways to create a PQExpBuffer object initially:
80  *
81  * PQExpBuffer stringptr = createPQExpBuffer();
82  * Both the PQExpBufferData and the data buffer are malloc'd.
83  *
84  * PQExpBufferData string;
85  * initPQExpBuffer(&string);
86  * The data buffer is malloc'd but the PQExpBufferData is presupplied.
87  * This is appropriate if the PQExpBufferData is a field of another
88  * struct.
89  *-------------------------
90  */
91 
92 /*------------------------
93  * createPQExpBuffer
94  * Create an empty 'PQExpBufferData' & return a pointer to it.
95  */
96 extern PQExpBuffer createPQExpBuffer(void);
97 
98 /*------------------------
99  * initPQExpBuffer
100  * Initialize a PQExpBufferData struct (with previously undefined contents)
101  * to describe an empty string.
102  */
103 extern void initPQExpBuffer(PQExpBuffer str);
104 
105 /*------------------------
106  * To destroy a PQExpBuffer, use either:
107  *
108  * destroyPQExpBuffer(str);
109  * free()s both the data buffer and the PQExpBufferData.
110  * This is the inverse of createPQExpBuffer().
111  *
112  * termPQExpBuffer(str)
113  * free()s the data buffer but not the PQExpBufferData itself.
114  * This is the inverse of initPQExpBuffer().
115  *
116  * NOTE: some routines build up a string using PQExpBuffer, and then
117  * release the PQExpBufferData but return the data string itself to their
118  * caller. At that point the data string looks like a plain malloc'd
119  * string.
120  */
121 extern void destroyPQExpBuffer(PQExpBuffer str);
122 extern void termPQExpBuffer(PQExpBuffer str);
123 
124 /*------------------------
125  * resetPQExpBuffer
126  * Reset a PQExpBuffer to empty
127  *
128  * Note: if possible, a "broken" PQExpBuffer is returned to normal.
129  */
130 extern void resetPQExpBuffer(PQExpBuffer str);
131 
132 /*------------------------
133  * enlargePQExpBuffer
134  * Make sure there is enough space for 'needed' more bytes in the buffer
135  * ('needed' does not include the terminating null).
136  *
137  * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case
138  * the buffer is left in "broken" state.)
139  */
140 extern int enlargePQExpBuffer(PQExpBuffer str, size_t needed);
141 
142 /*------------------------
143  * printfPQExpBuffer
144  * Format text data under the control of fmt (an sprintf-like format string)
145  * and insert it into str. More space is allocated to str if necessary.
146  * This is a convenience routine that does the same thing as
147  * resetPQExpBuffer() followed by appendPQExpBuffer().
148  */
149 extern void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3);
150 
151 /*------------------------
152  * appendPQExpBuffer
153  * Format text data under the control of fmt (an sprintf-like format string)
154  * and append it to whatever is already in str. More space is allocated
155  * to str if necessary. This is sort of like a combination of sprintf and
156  * strcat.
157  */
158 extern void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3);
159 
160 /*------------------------
161  * appendPQExpBufferVA
162  * Attempt to format data and append it to str. Returns true if done
163  * (either successful or hard failure), false if need to retry.
164  *
165  * Caution: callers must be sure to preserve their entry-time errno
166  * when looping, in case the fmt contains "%m".
167  */
168 extern bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) pg_attribute_printf(2, 0);
169 
170 /*------------------------
171  * appendPQExpBufferStr
172  * Append the given string to a PQExpBuffer, allocating more space
173  * if necessary.
174  */
175 extern void appendPQExpBufferStr(PQExpBuffer str, const char *data);
176 
177 /*------------------------
178  * appendPQExpBufferChar
179  * Append a single byte to str.
180  * Like appendPQExpBuffer(str, "%c", ch) but much faster.
181  */
182 extern void appendPQExpBufferChar(PQExpBuffer str, char ch);
183 
184 /*------------------------
185  * appendBinaryPQExpBuffer
186  * Append arbitrary binary data to a PQExpBuffer, allocating more space
187  * if necessary.
188  */
190  const char *data, size_t datalen);
191 
192 #endif /* PQEXPBUFFER_H */
#define pg_attribute_printf(f, a)
Definition: c.h:175
static void const char * fmt
const void * data
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
int enlargePQExpBuffer(PQExpBuffer str, size_t needed)
Definition: pqexpbuffer.c:172
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
struct PQExpBufferData PQExpBufferData
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2
void appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
Definition: pqexpbuffer.c:397
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
PQExpBufferData * PQExpBuffer
Definition: pqexpbuffer.h:51
void void bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) pg_attribute_printf(2
void void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
void void bool void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367