BinaryFileWriter¶
std::ofstream
を使って、バイナリファイルを書き出すクラスを実装する。
BinaryFileWriter.hpp
#pragma once
#include <memory> // std::shared_ptr, std::addressof
#include <string_view> // std::string_view
#include <string> // std::string
#include <type_traits> // std::is_trivially_copyable_v
#include "Common.hpp"
namespace seccamp
{
/// @brief バイナリファイルを書き出すクラス
class BinaryFileWriter
{
public:
/// @brief デフォルトコンストラクタ
[[nodiscard]]
BinaryFileWriter();
/// @brief ファイルを作成してオープンします。
/// @param path ファイルパス
[[nodiscard]]
explicit BinaryFileWriter(std::string_view path);
/// @brief ファイルがオープンされているかを返します。
/// @return オープンされている場合 true, それ以外の場合は false
[[nodiscard]]
bool isOpen() const noexcept;
/// @brief ファイルがオープンされているかを返します。
/// @return オープンされている場合 true, それ以外の場合は false
[[nodiscard]]
explicit operator bool() const noexcept;
/// @brief ファイルをオープンします。すでにオープンされている場合はクローズしてから再オープンします。
/// @param path ファイルパス
/// @return オープンに成功した場合 true, それ以外の場合は false
bool open(std::string_view path);
/// @brief ファイルをクローズします。
void close();
/// @brief ファイルにデータを書き込みます。
/// @param data 書き込むデータ
/// @param size データのサイズ(バイト)
void write(const void* data, size_t size);
/// @brief ファイルにデータを書き込みます。
/// @tparam T 書き込むデータの型
/// @param data 書き込むデータ
template <class T>
requires std::is_trivially_copyable_v<T>
void write(const T& data)
{
write(std::addressof(data), sizeof(T));
}
/// @brief ファイルの絶対パスを返します。
/// @return ファイルの絶対パス。ファイルがオープンされていない場合は空文字列
[[nodiscard]]
const std::string& fullPath() const noexcept;
private:
class Impl;
std::shared_ptr<Impl> m_pImpl;
};
}
BinaryFileWriter.cpp
#include <fstream> // std::ofstream
#include "BinaryFileWriter.hpp"
#include "FileSystem.hpp"
namespace seccamp
{
class BinaryFileWriter::Impl
{
public:
Impl() = default;
~Impl()
{
close();
}
[[nodiscard]]
bool isOpen() const noexcept
{
return m_file.is_open();
}
bool open(const std::string_view path)
{
if (m_file.is_open())
{
close();
}
m_file.open(std::string{ path }, std::ios::binary);
if (m_file.is_open())
{
m_fullPath = FileSystem::FullPath(path);
return true;
}
else
{
return false;
}
}
void close()
{
m_file.close();
m_fullPath.clear();
}
void write(const void* data, const size_t size)
{
m_file.write(static_cast<const char*>(data), size);
}
[[nodiscard]]
const std::string& fullPath() const noexcept
{
return m_fullPath;
}
private:
std::ofstream m_file;
std::string m_fullPath;
};
BinaryFileWriter::BinaryFileWriter()
: m_pImpl{ std::make_shared<Impl>() } {}
BinaryFileWriter::BinaryFileWriter(const std::string_view path)
: BinaryFileWriter{} // 移譲コンストラクタ
{
m_pImpl->open(path);
}
bool BinaryFileWriter::isOpen() const noexcept
{
return m_pImpl->isOpen();
}
BinaryFileWriter::operator bool() const noexcept
{
return m_pImpl->isOpen();
}
bool BinaryFileWriter::open(const std::string_view path)
{
return m_pImpl->open(path);
}
void BinaryFileWriter::close()
{
m_pImpl->close();
}
const std::string& BinaryFileWriter::fullPath() const noexcept
{
return m_pImpl->fullPath();
}
void BinaryFileWriter::write(const void* data, const size_t size)
{
m_pImpl->write(data, size);
}
}