| 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-2019, 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 | |