Skip to content

Commit

Permalink
Herix: Made loadintochunk recover from EOF issues (though that my not…
Browse files Browse the repository at this point in the history
… be an issue?)
  • Loading branch information
MinusGix committed Sep 14, 2019
1 parent 10f1648 commit 770e967
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 25 deletions.
63 changes: 39 additions & 24 deletions src/herix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::streamoff>(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<std::streamoff>(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<ChunkSize>(std::numeric_limits<std::streamsize>::max()));
assert(chunk.data.capacity() >= read_size);
assert(read_size <= static_cast<ChunkSize>(std::numeric_limits<std::streamsize>::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<char*>(chunk.data.data()), static_cast<std::streamsize>(chunk_size));
file.read(reinterpret_cast<char*>(chunk.data.data()), static_cast<std::streamsize>(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
}
Expand Down Expand Up @@ -268,9 +280,10 @@ std::optional<Byte> 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);
Expand All @@ -283,6 +296,8 @@ std::optional<Byte> Herix::readRaw (FilePosition pos) {
}
}

assert(cid.has_value());

Chunk& chunk = chunks.at(cid.value());

assert(pos >= chunk.start);
Expand Down
3 changes: 2 additions & 1 deletion src/herix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 770e967

Please sign in to comment.