[coding] buffered file writer is added

This commit is contained in:
Arsentiy Milchakov 2019-08-12 11:52:02 +03:00 committed by mpimenov
parent d5b6f4410d
commit 6dfacca341
6 changed files with 125 additions and 7 deletions

View file

@ -16,6 +16,8 @@ set(
base64.hpp
bit_streams.hpp
buffer_reader.hpp
buffered_file_writer.cpp
buffered_file_writer.hpp
bwt_coder.hpp
byte_stream.hpp
compressed_bit_vector.cpp

View file

@ -0,0 +1,75 @@
#include "coding/buffered_file_writer.hpp"
#include "coding/internal/file_data.hpp"
BufferedFileWriter::BufferedFileWriter(std::string const & fileName,
Op operation /* = OP_WRITE_TRUNCATE */,
size_t bufferSize /* = 4096 */)
: FileWriter(fileName, operation)
{
m_buf.reserve(bufferSize);
}
BufferedFileWriter::~BufferedFileWriter()
{
DropBuffer();
GetFileData().Flush();
}
void BufferedFileWriter::Seek(uint64_t pos)
{
DropBuffer();
FileWriter::Seek(pos);
}
uint64_t BufferedFileWriter::Pos() const
{
return FileWriter::Pos() + m_buf.size();
}
void BufferedFileWriter::Write(void const * p, size_t size)
{
// Need to use pointer arithmetic.
auto src = static_cast<uint8_t const *>(p);
while (size >= m_buf.capacity() - m_buf.size())
{
if (m_buf.empty())
{
FileWriter::Write(src, m_buf.capacity());
src += m_buf.capacity();
size -= m_buf.capacity();
}
else
{
auto const copyCount = m_buf.capacity() - m_buf.size();
std::copy(src, src + copyCount, std::back_inserter(m_buf));
FileWriter::Write(m_buf.data(), m_buf.size());
m_buf.clear();
src += copyCount;
size -= copyCount;
}
}
std::copy(src, src + size, std::back_inserter(m_buf));
}
uint64_t BufferedFileWriter::Size() const
{
return FileWriter::Size() + m_buf.size();
}
void BufferedFileWriter::Flush()
{
DropBuffer();
FileWriter::Flush();
}
void BufferedFileWriter::DropBuffer()
{
if (m_buf.empty())
return;
GetFileData().Write(m_buf.data(), m_buf.size());
m_buf.clear();
}

View file

@ -0,0 +1,29 @@
#pragma once
#include "coding/file_writer.hpp"
#include <cstdint>
#include <string>
#include <vector>
class BufferedFileWriter : public FileWriter
{
public:
explicit BufferedFileWriter(std::string const & fileName, Op operation = OP_WRITE_TRUNCATE,
size_t bufferSize = 4096);
// Writer overrides:
~BufferedFileWriter() override;
void Seek(uint64_t pos) override;
uint64_t Pos() const override;
void Write(void const * p, size_t size) override;
// FileWriter overrides:
uint64_t Size() const override;
void Flush() override;
private:
void DropBuffer();
std::vector<uint8_t> m_buf;
};

View file

@ -1,5 +1,6 @@
#include "testing/testing.hpp"
#include "coding/buffered_file_writer.hpp"
#include "coding/file_writer.hpp"
#include "coding/file_reader.hpp"
#include "coding/internal/file_data.hpp"
@ -212,16 +213,16 @@ void ReadTestData(Reader & r)
string const sub = s.substr(CHUNKS_COUNT * CHUNK_SIZE);
TEST_EQUAL(sub, TEST_STRING, (sub, TEST_STRING));
}
UNIT_TEST(FileWriter_Chunks)
template <typename WriterType>
void WriteToFileAndTest()
{
string const TEST_FILE = "FileWriter_Chunks.test";
{
FileWriter fileWriter(TEST_FILE, FileWriter::OP_WRITE_TRUNCATE);
WriterType fileWriter(TEST_FILE, FileWriter::OP_WRITE_TRUNCATE);
WriteTestData1(fileWriter);
}
{
FileWriter fileWriter(TEST_FILE, FileWriter::OP_WRITE_EXISTING);
WriterType fileWriter(TEST_FILE, FileWriter::OP_WRITE_EXISTING);
WriteTestData2(fileWriter);
}
{
@ -231,6 +232,16 @@ UNIT_TEST(FileWriter_Chunks)
FileWriter::DeleteFileX(TEST_FILE);
}
UNIT_TEST(FileWriter_Chunks)
{
WriteToFileAndTest<FileWriter>();
}
UNIT_TEST(BufferedFileWriter_Smoke)
{
WriteToFileAndTest<BufferedFileWriter>();
}
UNIT_TEST(MemWriter_Chunks)
{
string buffer;

View file

@ -12,7 +12,7 @@ FileWriter::FileWriter(string const & fileName, FileWriter::Op op)
FileWriter::~FileWriter()
{
Flush();
m_pFileData->Flush();
}
uint64_t FileWriter::Pos() const

View file

@ -47,8 +47,9 @@ public:
uint64_t Pos() const override;
void Write(void const * p, size_t size) override;
uint64_t Size() const;
void Flush();
virtual uint64_t Size() const;
virtual void Flush();
std::string const & GetName() const;
static void DeleteFileX(std::string const & fName);