diff --git a/src/herix.cpp b/src/herix.cpp index fb89be4..bc6a74e 100644 --- a/src/herix.cpp +++ b/src/herix.cpp @@ -129,51 +129,63 @@ size_t Herix::getFileSize () const { return std::filesystem::file_size(filename); } -void Herix::loadChunk (FilePositionStart pos) { - if (!file.is_open()) { - throw std::runtime_error("Attempting to load chunk whilst file was not open"); - } - - if (findChunk(pos).has_value()) { - throw std::runtime_error("Attempted to load chunk that is already partially loaded!"); - } - +void Herix::loadIntoChunk (FilePosition pos, ChunkSize read_size, ChunkID cid, Chunk& chunk, bool eof_handling) { file.seekg(static_cast(pos)); if (file.fail()) { - throw std::runtime_error("Failed to seek to position in file!"); + throw std::runtime_error("Failed to seek to position in file!: " + std::to_string(pos) + " | " + std::to_string(static_cast(pos))); } - // Half-formed. This has to be filled in. - //ChunkID cid = addChunk(Chunk(pos, chunk_size)); - ChunkID cid = getNewChunkID(); - chunks.emplace(std::make_pair(cid, Chunk(pos, chunk_size))); - - Chunk& chunk = chunks.at(cid); - chunk.data.resize(chunk_size); + chunk.data.resize(read_size); // Make sure there's enough space, there should be unless I'm misunderstanding - assert(chunk.data.capacity() >= chunk_size); - assert(chunk_size <= static_cast(std::numeric_limits::max())); + assert(chunk.data.capacity() >= read_size); + assert(read_size <= static_cast(std::numeric_limits::max())); file.clear(); // Characters are extracted and stored until: - // chunk_size characters were extracted and stored + // read_size characters were extracted and stored // or, EOF condition occurs on the input sequence. setstate(failbit|eofbit) is called. // the number of extracted cahracters can be queried using gcount // TODO: find a way around using reinterpret cast :| - file.read(reinterpret_cast(chunk.data.data()), static_cast(chunk_size)); + file.read(reinterpret_cast(chunk.data.data()), static_cast(read_size)); if (file.fail() && !file.eof()) { // fail, but not eof chunks.erase(cid); // I don't see anything about it being able to fail and not be in eof on my reference, but just in case throw std::runtime_error("Failed to read data from file!"); + } else if (file.fail() && file.eof()) { + if (eof_handling) { + // We are already handling eof.. so let's not continue. + throw std::runtime_error("Eof handling failed! Previous size: " + std::to_string(read_size) + ", attempted current: " + std::to_string(file.gcount())); + } + loadIntoChunk(pos, file.gcount(), cid, chunk, true); } else { - chunk.data.resize(file.gcount()); + std::streamsize gcount = file.gcount(); + chunk.data.resize(gcount); // Might as well shrink chunk.data.shrink_to_fit(); } } +void Herix::loadChunk (FilePositionStart pos, ChunkSize read_size) { + if (!file.is_open()) { + throw std::runtime_error("Attempting to load chunk whilst file was not open"); + } + + if (findChunk(pos).has_value()) { + throw std::runtime_error("Attempted to load chunk that is already partially loaded!"); + } + + // Half-formed. This has to be filled in. + //ChunkID cid = addChunk(Chunk(pos, chunk_size)); + ChunkID cid = getNewChunkID(); + chunks.emplace(std::make_pair(cid, Chunk(pos, chunk_size))); + + Chunk& chunk = chunks.at(cid); + + loadIntoChunk(pos, read_size, cid, chunk); +} + ChunkID Herix::getNewChunkID () { return c_count++; // return it's current value, then add 1 } @@ -268,9 +280,10 @@ std::optional Herix::readRaw (FilePosition pos) { if (!cid.has_value()) { try { - loadChunk(getAlignedChunk(pos)); + loadChunk(getAlignedChunk(pos), chunk_size); } catch (...) { - return std::nullopt; + throw; + //return std::nullopt; } cid = findChunk(pos); @@ -283,6 +296,8 @@ std::optional Herix::readRaw (FilePosition pos) { } } + assert(cid.has_value()); + Chunk& chunk = chunks.at(cid.value()); assert(pos >= chunk.start); diff --git a/src/herix.hpp b/src/herix.hpp index e25298f..82adc5b 100644 --- a/src/herix.hpp +++ b/src/herix.hpp @@ -81,7 +81,8 @@ class Herix { std::fstream file; void destroyChunk (ChunkID id); - void loadChunk (FilePosition pos); + void loadChunk (FilePosition pos, ChunkSize read_size); + void loadIntoChunk (FilePosition pos, ChunkSize read_size, ChunkID cid, Chunk& chunk, bool eof_handling=false); ChunkID getNewChunkID (); /// Swapping is used to note that we're swapping file (such as with saveas)