Boost logo

Boost Users :

Subject: Re: [Boost-users] [iostreams] why doesn't file_sink flush?
From: Andy Schweitzer (a.schweitzer.grps_at_[hidden])
Date: 2009-05-05 22:49:50


eg wrote:
> Andy Schweitzer wrote:
>> eg wrote:
>>> Andrew Schweitzer wrote:
>
>>
>> Thanks, I've read that, but it doesn't directly answer my questions.
>> In particular, a) fstream flush seems to work fine, so I'm curious why
>> file_sink doesn't call it and b) given that you can't flush a
>> file_sink what is the appropriate implementation - it seems like there
>> would be one that is relatively straight-forward.
>
>
> Good questions.
> I dont know why file_sink or file_descriptor_sink are not currently
> implemented with the flushable_tag.
>
> It looks like it would be very straightforward to add.
>
> My usage of iostreams has always involved the gzip filters, which are
> not flushable either, so I haven't run into this and don't have a
> solution... other than adding flush support to file_sink.
>
> Is there more to it than adding the flushable_tag, and adding a flush
> function to basic_file_sink and basic_file<Ch>, the latter simply
> calling pimpl->file_.flush() ?

That's a good idea. I don't know, I don't know the library well enough.
That seemed like more code... but maybe a better idea. I tried this,
wrapping fstream. Not sure if there's a reason not to do this:

class flushable_file_sink
{
public:
        flushable_file_sink(const std::string& path,
                BOOST_IOS::openmode mode = BOOST_IOS::out)
                           :m_fs(path.c_str(), mode), m_strName(path), m_mode(mode)
        {
        }

        flushable_file_sink(const flushable_file_sink& rOther)
        {
                m_strName = rOther.m_strName;
                m_mode = rOther.m_mode;
                rOther.m_fs.close();
                m_fs.open(m_strName.c_str(), m_mode);
        }

        struct category
         : output_seekable,
           device_tag,
           closable_tag,
                  flushable_tag
        { };

     typedef char char_type;

        std::streamsize write(const char* buf, std::streamsize n)
        {
                m_fs.write(buf, n);
                return n;
        }

        bool flush()
        {
                m_fs.flush();
                return true;
        }

     void close()
        {
                m_bOpen = m_fs.is_open();
                m_fs.close();
        }

     void close(std::ios_base::openmode mode)
        {
                m_fs.close();
        }

     std::streamsize read(char_type* s, std::streamsize n)
        {
                m_fs.read(s, n);
                return n;
        }

     std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
                          BOOST_IOS::openmode which =
                              BOOST_IOS::in | BOOST_IOS::out )
        {
                m_fs.seekp(off, way);
                m_fs.seekg(off, way);
                return off;
        }

private:
        mutable fstream m_fs;
        string m_strName;
        BOOST_IOS::openmode m_mode;
        bool m_bOpen;
};


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net