* Make sure conn's input buffer can hold bytes_needed bytes (caller must * include already-stored data into the value!) * * Returns 0 on success, EOF if failed to enlarge buffer */
| 392 | * Returns 0 on success, EOF if failed to enlarge buffer |
| 393 | */ |
| 394 | int |
| 395 | pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn) |
| 396 | { |
| 397 | int newsize = conn->inBufSize; |
| 398 | char *newbuf; |
| 399 | |
| 400 | /* Quick exit if we have enough space */ |
| 401 | if (bytes_needed <= (size_t) newsize) |
| 402 | return 0; |
| 403 | |
| 404 | /* |
| 405 | * Before concluding that we need to enlarge the buffer, left-justify |
| 406 | * whatever is in it and recheck. The caller's value of bytes_needed |
| 407 | * includes any data to the left of inStart, but we can delete that in |
| 408 | * preference to enlarging the buffer. It's slightly ugly to have this |
| 409 | * function do this, but it's better than making callers worry about it. |
| 410 | */ |
| 411 | bytes_needed -= conn->inStart; |
| 412 | |
| 413 | if (conn->inStart < conn->inEnd) |
| 414 | { |
| 415 | if (conn->inStart > 0) |
| 416 | { |
| 417 | memmove(conn->inBuffer, conn->inBuffer + conn->inStart, |
| 418 | conn->inEnd - conn->inStart); |
| 419 | conn->inEnd -= conn->inStart; |
| 420 | conn->inCursor -= conn->inStart; |
| 421 | conn->inStart = 0; |
| 422 | } |
| 423 | } |
| 424 | else |
| 425 | { |
| 426 | /* buffer is logically empty, reset it */ |
| 427 | conn->inStart = conn->inCursor = conn->inEnd = 0; |
| 428 | } |
| 429 | |
| 430 | /* Recheck whether we have enough space */ |
| 431 | if (bytes_needed <= (size_t) newsize) |
| 432 | return 0; |
| 433 | |
| 434 | /* |
| 435 | * If we need to enlarge the buffer, we first try to double it in size; if |
| 436 | * that doesn't work, enlarge in multiples of 8K. This avoids thrashing |
| 437 | * the malloc pool by repeated small enlargements. |
| 438 | * |
| 439 | * Note: tests for newsize > 0 are to catch integer overflow. |
| 440 | */ |
| 441 | do |
| 442 | { |
| 443 | newsize *= 2; |
| 444 | } while (newsize > 0 && bytes_needed > (size_t) newsize); |
| 445 | |
| 446 | if (newsize > 0 && bytes_needed <= (size_t) newsize) |
| 447 | { |
| 448 | newbuf = realloc(conn->inBuffer, newsize); |
| 449 | if (newbuf) |
| 450 | { |
| 451 | /* realloc succeeded */ |
no test coverage detected