enh(Foundation): add a counted StreamCopier copy that does not seek
StreamCopier can already copy a bounded number of bytes, but only through
copyStreamRange() / copyStreamRange64(), which begin with
istr.seekg(rangeStart, std::ios_base::beg);That makes the bounded copy unavailable to code that reads sequentially from the current position on a stream that may not be seekable.
The rest of copyStreamRangeImpl() is exactly the loop such code needs: the
buffer is clamped to the requested length
if (bufferSize > static_cast<std::size_t>(rangeLength))
bufferSize = static_cast<std::size_t>(rangeLength);so the allocation stays independent of the requested count, and the return value reports how much was actually copied, which is what distinguishes a complete read from a truncated one.
Proposal: factor the seek out and expose the loop.
template <typename T>
static T copyStreamCountedImpl(std::istream& istr, std::ostream& ostr,
std::streamsize count, std::size_t bufferSize);
static std::streamsize copyStreamN(std::istream& istr, std::ostream& ostr,
std::streamsize count, std::size_t bufferSize = 8192);
static Poco::UInt64 copyStreamN64(std::istream& istr, std::ostream& ostr,
std::streamsize count, std::size_t bufferSize = 8192);copyStreamRangeImpl() then becomes the seek plus a call to the counted
variant, so existing callers are unaffected and the change is additive.
Call sites that currently hand-roll the same loop:
Zip/src/ZipArchiveInfo.cpp,ZipArchiveInfo64::parse()-- reads the ZIP64 extensible data sector in chunks so a declared record size cannot drive the allocation.Net/src/HTTPFixedLengthStream.cppandNet/src/MultipartReader.cppread a bounded amount in a similar way.
Deliberately not proposed for a patch release: this adds public Foundation API.
Source: pocoproject/poco