mirror of https://github.com/libAthena/athena.git
Add TransactionalFileWriter
This commit is contained in:
parent
a1acdac588
commit
d2e080a515
|
@ -66,6 +66,56 @@ private:
|
|||
atUint64 m_bytePosition;
|
||||
bool m_globalErr;
|
||||
};
|
||||
|
||||
class TransactionalFileWriter : public IStreamWriter
|
||||
{
|
||||
#if _WIN32
|
||||
std::wstring m_filename;
|
||||
#else
|
||||
std::string m_filename;
|
||||
#endif
|
||||
bool m_overwrite, m_globalErr;
|
||||
std::vector<uint8_t> m_deferredBuffer;
|
||||
atUint64 m_position = 0;
|
||||
public:
|
||||
TransactionalFileWriter(const std::string& filename, bool overwrite = true, bool globalErr=true)
|
||||
: m_overwrite(overwrite), m_globalErr(globalErr)
|
||||
{
|
||||
#if _WIN32
|
||||
m_filename = utility::utf8ToWide(m_filename);
|
||||
#else
|
||||
m_filename = filename;
|
||||
#endif
|
||||
}
|
||||
TransactionalFileWriter(const std::wstring& filename, bool overwrite = true, bool globalErr=true)
|
||||
: m_overwrite(overwrite), m_globalErr(globalErr)
|
||||
{
|
||||
#if _WIN32
|
||||
m_filename = filename;
|
||||
#else
|
||||
m_filename = utility::wideToUtf8(filename);
|
||||
#endif
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
if (m_deferredBuffer.size())
|
||||
{
|
||||
FileWriter w(m_filename, m_overwrite, m_globalErr);
|
||||
w.writeUBytes(m_deferredBuffer.data(), m_deferredBuffer.size());
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void cancel() { m_deferredBuffer.clear(); m_position = 0; }
|
||||
|
||||
inline atUint64 position() const { return m_position; }
|
||||
inline atUint64 length() const { return m_deferredBuffer.size(); }
|
||||
void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current);
|
||||
void writeUBytes(const atUint8* data, atUint64 len);
|
||||
|
||||
~TransactionalFileWriter() { flush(); }
|
||||
};
|
||||
}
|
||||
} // Athena
|
||||
|
||||
|
|
|
@ -16,7 +16,11 @@ FileWriter::FileWriter(const std::string& filename, bool overwrite, bool globalE
|
|||
m_bytePosition(0),
|
||||
m_globalErr(globalErr)
|
||||
{
|
||||
#if _WIN32
|
||||
m_filename = utility::utf8ToWide(m_filename);
|
||||
#else
|
||||
m_filename = filename;
|
||||
#endif
|
||||
open(overwrite);
|
||||
}
|
||||
|
||||
|
@ -25,7 +29,11 @@ FileWriter::FileWriter(const std::wstring& filename, bool overwrite, bool global
|
|||
m_bytePosition(0),
|
||||
m_globalErr(globalErr)
|
||||
{
|
||||
#if _WIN32
|
||||
m_filename = filename;
|
||||
#else
|
||||
m_filename = utility::wideToUtf8(filename);
|
||||
#endif
|
||||
open(overwrite);
|
||||
}
|
||||
|
||||
|
@ -121,5 +129,33 @@ void FileWriter::writeUBytes(const atUint8* data, atUint64 len)
|
|||
}
|
||||
}
|
||||
|
||||
void TransactionalFileWriter::seek(atInt64 pos, SeekOrigin origin)
|
||||
{
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin::Begin:
|
||||
m_position = pos;
|
||||
break;
|
||||
case SeekOrigin::Current:
|
||||
m_position += pos;
|
||||
break;
|
||||
case SeekOrigin::End:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TransactionalFileWriter::writeUBytes(const atUint8* data, atUint64 len)
|
||||
{
|
||||
atUint64 neededSz = m_position + len;
|
||||
if (neededSz > m_deferredBuffer.size())
|
||||
{
|
||||
m_deferredBuffer.reserve(neededSz * 2);
|
||||
m_deferredBuffer.resize(neededSz);
|
||||
}
|
||||
|
||||
memmove(m_deferredBuffer.data() + m_position, data, len);
|
||||
m_position += len;
|
||||
}
|
||||
|
||||
}
|
||||
} // Athena
|
||||
|
|
Loading…
Reference in New Issue