* pqResultAlloc - * Allocate subsidiary storage for a PGresult. * * nBytes is the amount of space needed for the object. * If isBinary is true, we assume that we need to align the object on * a machine allocation boundary. * If isBinary is false, we assume the object is a char string and can * be allocated on any byte boundary. */
| 560 | * be allocated on any byte boundary. |
| 561 | */ |
| 562 | void * |
| 563 | pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary) |
| 564 | { |
| 565 | char *space; |
| 566 | PGresult_data *block; |
| 567 | |
| 568 | if (!res) |
| 569 | return NULL; |
| 570 | |
| 571 | if (nBytes <= 0) |
| 572 | return res->null_field; |
| 573 | |
| 574 | /* |
| 575 | * If alignment is needed, round up the current position to an alignment |
| 576 | * boundary. |
| 577 | */ |
| 578 | if (isBinary) |
| 579 | { |
| 580 | int offset = res->curOffset % PGRESULT_ALIGN_BOUNDARY; |
| 581 | |
| 582 | if (offset) |
| 583 | { |
| 584 | res->curOffset += PGRESULT_ALIGN_BOUNDARY - offset; |
| 585 | res->spaceLeft -= PGRESULT_ALIGN_BOUNDARY - offset; |
| 586 | } |
| 587 | } |
| 588 | |
| 589 | /* If there's enough space in the current block, no problem. */ |
| 590 | if (nBytes <= (size_t) res->spaceLeft) |
| 591 | { |
| 592 | space = res->curBlock->space + res->curOffset; |
| 593 | res->curOffset += nBytes; |
| 594 | res->spaceLeft -= nBytes; |
| 595 | return space; |
| 596 | } |
| 597 | |
| 598 | /* |
| 599 | * If the requested object is very large, give it its own block; this |
| 600 | * avoids wasting what might be most of the current block to start a new |
| 601 | * block. (We'd have to special-case requests bigger than the block size |
| 602 | * anyway.) The object is always given binary alignment in this case. |
| 603 | */ |
| 604 | if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD) |
| 605 | { |
| 606 | size_t alloc_size = nBytes + PGRESULT_BLOCK_OVERHEAD; |
| 607 | |
| 608 | block = (PGresult_data *) malloc(alloc_size); |
| 609 | if (!block) |
| 610 | return NULL; |
| 611 | res->memorySize += alloc_size; |
| 612 | space = block->space + PGRESULT_BLOCK_OVERHEAD; |
| 613 | if (res->curBlock) |
| 614 | { |
| 615 | /* |
| 616 | * Tuck special block below the active block, so that we don't |
| 617 | * have to waste the free space in the active block. |
| 618 | */ |
| 619 | block->next = res->curBlock->next; |
no outgoing calls
no test coverage detected