/ CPLReadLineBuffer() */ / Fetch readline buffer, and ensure it is the desired size, */ reallocating if needed. Manages TLS (thread local storage) */ issues for the buffer. */ We use a special trick to track the actual size of the buffer */ The first 4 bytes are reserved to store it as a int, hence the */ -4 / +4 hacks
| 498 | /* -4 / +4 hacks with the size and pointer. */ |
| 499 | /************************************************************************/ |
| 500 | static char *CPLReadLineBuffer(int nRequiredSize) |
| 501 | |
| 502 | { |
| 503 | |
| 504 | /* -------------------------------------------------------------------- */ |
| 505 | /* A required size of -1 means the buffer should be freed. */ |
| 506 | /* -------------------------------------------------------------------- */ |
| 507 | if (nRequiredSize == -1) |
| 508 | { |
| 509 | int bMemoryError = FALSE; |
| 510 | void *pRet = CPLGetTLSEx(CTLS_RLBUFFERINFO, &bMemoryError); |
| 511 | if (pRet != nullptr) |
| 512 | { |
| 513 | CPLFree(pRet); |
| 514 | CPLSetTLS(CTLS_RLBUFFERINFO, nullptr, FALSE); |
| 515 | } |
| 516 | return nullptr; |
| 517 | } |
| 518 | |
| 519 | /* -------------------------------------------------------------------- */ |
| 520 | /* If the buffer doesn't exist yet, create it. */ |
| 521 | /* -------------------------------------------------------------------- */ |
| 522 | int bMemoryError = FALSE; |
| 523 | GUInt32 *pnAlloc = |
| 524 | static_cast<GUInt32 *>(CPLGetTLSEx(CTLS_RLBUFFERINFO, &bMemoryError)); |
| 525 | if (bMemoryError) |
| 526 | return nullptr; |
| 527 | |
| 528 | if (pnAlloc == nullptr) |
| 529 | { |
| 530 | pnAlloc = static_cast<GUInt32 *>(VSI_MALLOC_VERBOSE(200)); |
| 531 | if (pnAlloc == nullptr) |
| 532 | return nullptr; |
| 533 | *pnAlloc = 196; |
| 534 | CPLSetTLS(CTLS_RLBUFFERINFO, pnAlloc, TRUE); |
| 535 | } |
| 536 | |
| 537 | /* -------------------------------------------------------------------- */ |
| 538 | /* If it is too small, grow it bigger. */ |
| 539 | /* -------------------------------------------------------------------- */ |
| 540 | if (static_cast<int>(*pnAlloc) - 1 < nRequiredSize) |
| 541 | { |
| 542 | const int nNewSize = nRequiredSize + 4 + 500; |
| 543 | if (nNewSize <= 0) |
| 544 | { |
| 545 | VSIFree(pnAlloc); |
| 546 | CPLSetTLS(CTLS_RLBUFFERINFO, nullptr, FALSE); |
| 547 | CPLError(CE_Failure, CPLE_OutOfMemory, |
| 548 | "CPLReadLineBuffer(): Trying to allocate more than " |
| 549 | "2 GB."); |
| 550 | return nullptr; |
| 551 | } |
| 552 | |
| 553 | GUInt32 *pnAllocNew = |
| 554 | static_cast<GUInt32 *>(VSI_REALLOC_VERBOSE(pnAlloc, nNewSize)); |
| 555 | if (pnAllocNew == nullptr) |
| 556 | { |
| 557 | VSIFree(pnAlloc); |
no test coverage detected