32 バイト文字を取り込み、別の ostream オブジェクトにバイト単位で配置するカスタム strbuf を作成しようとしています。
以下はそのコードです。
エラーを特定することはできませんが、main.cpp でリンクした方法を個人的に疑っています。mybuf私によると、ofile_cp は、set_rdbuf() で私の utf32_buffer オブジェクトに置き換えられる必要がある構築中に独自のバッファーを宣言する必要があります。その後、すべての I/O は、バッファーを介して基になる ofstream に移動する必要がありofile_c1ます。ただし、ファイルには何も出力されません。誰でもここでバグを指摘できますか?
main.cpp (カスタム strbuf を使用)
#include "utf8.h"
#include <fstream>
#include <cstdint>
#include <iostream>
int main()
{
std::basic_ofstream<my::code_point> ofile_cp("temp1");
std::ofstream ofile_c1("temp3");
utf32_buffer mybuf(ofile_c1, 4096);
ofile_cp.set_rdbuf(&mybuf);
std::ofstream ofile_c2("temp2");
char c = 'a';
ofile_cp << c;
ofile_c2 << c;
return 0;
}
utf.cpp はカスタム strbuf を定義します
#include <streambuf>
#include <vector> //as buffer in utf32_buffer
#include <functional> //for less_equal()
#include <cassert> //for assert()
#include <ostream>
#include <cstdint> //for uint32_t
namespace my
{
typedef std::uint32_t code_point;
}
using namespace my;
class utf32_buffer : public std::basic_streambuf<code_point>
{
public:
explicit utf32_buffer(std::ostream &sink, std::size_t buff_sz = 256);
private:
int_type overflow(int_type ch);
int sync();
bool flush();
utf32_buffer(const utf32_buffer &);
utf32_buffer &operator=(const utf32_buffer &);
private:
std::ostream &sink_;
std::vector<code_point> buffer_;
};
utf32_buffer::utf32_buffer(std::ostream &sink, std::size_t buff_sz) :
sink_(sink),
buffer_(buff_sz + 1)
{
sink_.clear();
code_point *base = &buffer_.front();
setp(base, base + buffer_.size() - 1);
}
utf32_buffer::int_type utf32_buffer::overflow(utf32_buffer::int_type ch)
{
if (sink_ && ch != traits_type::eof())
{
assert(std::less_equal<code_point *>()(pptr(), epptr()));
*pptr() = std::char_traits<code_point>::to_char_type(ch);
pbump(1);
if (flush())
{
return 0;
}
}
return traits_type::eof();
}
int utf32_buffer::sync()
{
return flush() ? 0 : -1;
}
bool utf32_buffer::flush()
{
assert(std::less_equal<code_point *>()(pptr(), epptr()));
std::ptrdiff_t n = pptr() - pbase();
pbump(-n);
const int cpsz = sizeof(code_point *);
union
{
char * cp_char;
code_point *cpptr;
};
cpptr = pbase();
return bool(sink_.write(cp_char, n * cpsz));
}