自定义strbuf不会在文件中放置任何内容

时间:2014-01-26 10:03:50

标签: c++ iostream streambuf

我正在尝试创建一个自定义strbuf,它接受32字节字符并将它们放在另一个ostream对象中。

以下是它的代码:

我个人怀疑我在main.cpp中链接它的方式虽然我无法确定其中的错误。根据我的说法,ofile_cp应该在构造期间声明它自己的缓冲区,它应该被set_rdbuf()中的utf32_buffer对象mybuf替换。之后,任何I / O都应通过我的缓冲区到基础流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));
}

0 个答案:

没有答案