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-2021, 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; 49 } PQExpBufferData; 50 51 typedef PQExpBufferData *PQExpBuffer; 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 * appendPQExpBufferStr 162 * Append the given string to a PQExpBuffer, allocating more space 163 * if necessary. 164 */ 165 extern void appendPQExpBufferStr(PQExpBuffer str, const char *data); 166 167 /*------------------------ 168 * appendPQExpBufferChar 169 * Append a single byte to str. 170 * Like appendPQExpBuffer(str, "%c", ch) but much faster. 171 */ 172 extern void appendPQExpBufferChar(PQExpBuffer str, char ch); 173 174 /*------------------------ 175 * appendBinaryPQExpBuffer 176 * Append arbitrary binary data to a PQExpBuffer, allocating more space 177 * if necessary. 178 */ 179 extern void appendBinaryPQExpBuffer(PQExpBuffer str, 180 const char *data, size_t datalen); 181 182 #endif /* PQEXPBUFFER_H */ 183