Added utilty functions to read an entire file.

This commit is contained in:
2023-11-19 23:45:35 +01:00
parent 0e90cabb7e
commit ce7a7b15c7
2 changed files with 112 additions and 0 deletions

View File

@@ -63,6 +63,60 @@ StreamError Stream::writeString(std::string_view str)
return writeSpan(str.begin(), str.end());
}
StreamError Stream::getTotalLength(std::size_t& outLength)
{
const StreamFeatures features = getFeatures();
if (!features.tell || !features.seek) {
return StreamError::NOT_SUPPORTED;
}
const std::size_t origPos = tell();
if (StreamError error = seek(0, SeekMode::RELATIVE_TO_END); error != StreamError::SUCCESS)
{
return error;
}
outLength = tell();
if (StreamError error = seek(static_cast<std::intptr_t>(origPos)); error != StreamError::SUCCESS)
{
return error;
}
return StreamError::SUCCESS;
}
StreamError Stream::readRest(TypelessBuffer& outBuffer)
{
// first try to allocate everything at once
std::size_t length = 0;
if (StreamError lengthError = getTotalLength(length); lengthError == StreamError::SUCCESS)
{
MIJIN_ASSERT(getFeatures().tell, "How did you find the length if you cannot tell()?");
length -= tell();
outBuffer.resize(length);
if (StreamError error = readRaw(outBuffer.data(), length); error != StreamError::SUCCESS)
{
return error;
}
return StreamError::SUCCESS;
}
// could not determine the size, read chunk-wise
static constexpr std::size_t CHUNK_SIZE = 4096;
std::array<std::byte, CHUNK_SIZE> chunk = {};
while (!isAtEnd())
{
std::size_t bytesRead = 0;
if (StreamError error = readRaw(chunk, true, &bytesRead); error != StreamError::SUCCESS)
{
return error;
}
outBuffer.resize(outBuffer.byteSize() + bytesRead);
std::span<std::byte> bufferBytes = outBuffer.makeSpan<std::byte>();
std::copy_n(chunk.begin(), bytesRead, bufferBytes.end() - static_cast<long>(bytesRead));
}
return StreamError::SUCCESS;
}
FileStream::~FileStream()
{
if (handle) {