Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "postgres_fe.h"
00026
00027 #include <limits.h>
00028
00029 #include "pqexpbuffer.h"
00030
00031 #ifdef WIN32
00032 #include "win32.h"
00033 #endif
00034
00035
00036
00037 static const char oom_buffer[1] = "";
00038
00039
00040
00041
00042
00043
00044
00045 static void
00046 markPQExpBufferBroken(PQExpBuffer str)
00047 {
00048 if (str->data != oom_buffer)
00049 free(str->data);
00050
00051
00052
00053
00054
00055
00056
00057 str->data = (char *) oom_buffer;
00058 str->len = 0;
00059 str->maxlen = 0;
00060 }
00061
00062
00063
00064
00065
00066
00067 PQExpBuffer
00068 createPQExpBuffer(void)
00069 {
00070 PQExpBuffer res;
00071
00072 res = (PQExpBuffer) malloc(sizeof(PQExpBufferData));
00073 if (res != NULL)
00074 initPQExpBuffer(res);
00075
00076 return res;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085 void
00086 initPQExpBuffer(PQExpBuffer str)
00087 {
00088 str->data = (char *) malloc(INITIAL_EXPBUFFER_SIZE);
00089 if (str->data == NULL)
00090 {
00091 str->data = (char *) oom_buffer;
00092 str->maxlen = 0;
00093 str->len = 0;
00094 }
00095 else
00096 {
00097 str->maxlen = INITIAL_EXPBUFFER_SIZE;
00098 str->len = 0;
00099 str->data[0] = '\0';
00100 }
00101 }
00102
00103
00104
00105
00106
00107
00108
00109 void
00110 destroyPQExpBuffer(PQExpBuffer str)
00111 {
00112 if (str)
00113 {
00114 termPQExpBuffer(str);
00115 free(str);
00116 }
00117 }
00118
00119
00120
00121
00122
00123
00124 void
00125 termPQExpBuffer(PQExpBuffer str)
00126 {
00127 if (str->data != oom_buffer)
00128 free(str->data);
00129
00130 str->data = (char *) oom_buffer;
00131 str->maxlen = 0;
00132 str->len = 0;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 void
00142 resetPQExpBuffer(PQExpBuffer str)
00143 {
00144 if (str)
00145 {
00146 if (str->data != oom_buffer)
00147 {
00148 str->len = 0;
00149 str->data[0] = '\0';
00150 }
00151 else
00152 {
00153
00154 initPQExpBuffer(str);
00155 }
00156 }
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 int
00168 enlargePQExpBuffer(PQExpBuffer str, size_t needed)
00169 {
00170 size_t newlen;
00171 char *newdata;
00172
00173 if (PQExpBufferBroken(str))
00174 return 0;
00175
00176
00177
00178
00179
00180
00181 if (needed >= ((size_t) INT_MAX - str->len))
00182 {
00183 markPQExpBufferBroken(str);
00184 return 0;
00185 }
00186
00187 needed += str->len + 1;
00188
00189
00190
00191 if (needed <= str->maxlen)
00192 return 1;
00193
00194
00195
00196
00197
00198
00199 newlen = (str->maxlen > 0) ? (2 * str->maxlen) : 64;
00200 while (needed > newlen)
00201 newlen = 2 * newlen;
00202
00203
00204
00205
00206
00207
00208 if (newlen > (size_t) INT_MAX)
00209 newlen = (size_t) INT_MAX;
00210
00211 newdata = (char *) realloc(str->data, newlen);
00212 if (newdata != NULL)
00213 {
00214 str->data = newdata;
00215 str->maxlen = newlen;
00216 return 1;
00217 }
00218
00219 markPQExpBufferBroken(str);
00220 return 0;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230 void
00231 printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
00232 {
00233 va_list args;
00234 size_t avail;
00235 int nprinted;
00236
00237 resetPQExpBuffer(str);
00238
00239 if (PQExpBufferBroken(str))
00240 return;
00241
00242 for (;;)
00243 {
00244
00245
00246
00247
00248
00249 if (str->maxlen > str->len + 16)
00250 {
00251 avail = str->maxlen - str->len - 1;
00252 va_start(args, fmt);
00253 nprinted = vsnprintf(str->data + str->len, avail,
00254 fmt, args);
00255 va_end(args);
00256
00257
00258
00259
00260
00261
00262 if (nprinted >= 0 && nprinted < (int) avail - 1)
00263 {
00264
00265 str->len += nprinted;
00266 break;
00267 }
00268 }
00269
00270 if (!enlargePQExpBuffer(str, str->maxlen))
00271 return;
00272 }
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 void
00284 appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
00285 {
00286 va_list args;
00287 size_t avail;
00288 int nprinted;
00289
00290 if (PQExpBufferBroken(str))
00291 return;
00292
00293 for (;;)
00294 {
00295
00296
00297
00298
00299
00300 if (str->maxlen > str->len + 16)
00301 {
00302 avail = str->maxlen - str->len - 1;
00303 va_start(args, fmt);
00304 nprinted = vsnprintf(str->data + str->len, avail,
00305 fmt, args);
00306 va_end(args);
00307
00308
00309
00310
00311
00312
00313 if (nprinted >= 0 && nprinted < (int) avail - 1)
00314 {
00315
00316 str->len += nprinted;
00317 break;
00318 }
00319 }
00320
00321 if (!enlargePQExpBuffer(str, str->maxlen))
00322 return;
00323 }
00324 }
00325
00326
00327
00328
00329
00330
00331 void
00332 appendPQExpBufferStr(PQExpBuffer str, const char *data)
00333 {
00334 appendBinaryPQExpBuffer(str, data, strlen(data));
00335 }
00336
00337
00338
00339
00340
00341
00342 void
00343 appendPQExpBufferChar(PQExpBuffer str, char ch)
00344 {
00345
00346 if (!enlargePQExpBuffer(str, 1))
00347 return;
00348
00349
00350 str->data[str->len] = ch;
00351 str->len++;
00352 str->data[str->len] = '\0';
00353 }
00354
00355
00356
00357
00358
00359
00360
00361 void
00362 appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
00363 {
00364
00365 if (!enlargePQExpBuffer(str, datalen))
00366 return;
00367
00368
00369 memcpy(str->data + str->len, data, datalen);
00370 str->len += datalen;
00371
00372
00373
00374
00375
00376 str->data[str->len] = '\0';
00377 }