/* * Created by Brett on 29/01/23. * Licensed under GNU General Public License V3.0 * See LICENSE file for license detail */ #include <blt/fs/filesystem.h> #include <cstring> #include "blt/std/logging.h" blt::fs::fstream_block_reader::fstream_block_reader(std::fstream& stream, size_t bufferSize) : block_reader(bufferSize), m_stream(stream), m_buffer(new char[bufferSize]) { if (!m_stream.good() || m_stream.fail()) BLT_WARN("Provided std::fstream is not good! Clearing!"); m_stream.clear(); } int blt::fs::fstream_block_reader::read(char* buffer, size_t bytes) { if (readIndex == 0) m_stream.read(m_buffer, (long) m_bufferSize); if (readIndex + bytes >= m_bufferSize) { // copy out all the data from the current buffer auto bytesLeft = m_bufferSize - readIndex; memcpy(buffer, m_buffer + readIndex, bytesLeft); readIndex = 0; // now to prevent large scale reading in small blocks, we should just read the entire thing into the buffer. m_stream.read(buffer + bytesLeft, (long) (bytes - bytesLeft)); } else { // but in the case that the size of the data read is small, we should read in blocks and copy from that buffer // that should be quicker since file operations are slow. std::memcpy(buffer, m_buffer + readIndex, bytes); readIndex += bytes; } return 0; } int blt::fs::fstream_block_writer::write(char* buffer, size_t bytes) { if (writeIndex + bytes >= m_bufferSize) { // in an attempt to stay efficient we write out the old buffer and the new buffer // since there is a good chance there is more than a buffer's worth of data being written // otherwise the buffer is almost full and can be written anyway. (this might be bad for performance especially if the FS wants round numbers) m_stream.write(m_buffer, (long) writeIndex); writeIndex = 0; m_stream.write(buffer, (long) bytes); } else { std::memcpy(m_buffer + writeIndex, buffer, bytes); writeIndex += bytes; } return 0; } void blt::fs::fstream_block_writer::flush_internal() { m_stream.write(m_buffer, (long) writeIndex); writeIndex = 0; }