boost::iostreams пару вопросов
От: nen777w  
Дата: 08.07.11 15:45
Оценка:
Есть некоторая функция принимающая на вход
std::ostream

и пишущая туда всякую фигню.

Есть контрол GUI в который хотелось бы это фигню перенаправить.

Что Я делаю.
Пишу свой девайс для этого контрола:

  "класс девайса"
class    richedit_device
{
public:
    typedef char                                    char_type;
    typedef boost::iostreams::seekable_device_tag    category;

    richedit_device(CRichEditCtrlEx& rich_edt) : m_rich_edt(rich_edt) {}

    std::streamsize write(const char_type* s, std::streamsize n)
    { 
        return n;
    }

    std::streamsize read(char* s, std::streamsize n)
    {
        assert(!"RICH EDIT DEVICE DO NOT SUPPORT READ OPERATION!!!!");
        return 0;
    }

    boost::iostreams::stream_offset seek(boost::iostreams::stream_offset off, std::ios_base::seekdir way)
    {
        assert(!"RICH EDIT DEVICE DO NOT SUPPORT SEEK OPERATION!!!!");
        return 0;
    }
private:
    CRichEditCtrlEx& m_rich_edt;
};


Теперь вопрос номер 1.
Девайс пришлось сделать категрии seekable_device_tag, хотя мне вполне бы мог подойти и sink_tag.
Но засада что по другому к std::ostream закастить:
namespace io = boost::iostreams;
io::stream<richedit_device> rich_edt_stream(m_log_window);
std::ostream(&rich_edt_stream);

просто не получится.
Во общем мне кажется что это криво как то, ну да ладно это фигня в принципе.
Работает.

Но теперь вопрос второй.

rich_edt_stream << "test";


это успешно будет записано во внутренний буффер boost::iostreams::stream, который равен 4100 (интересно число) и во общем пока или flush или буфер не заполнится
мы вызов в нашем девайсе richedit_device::write не получим.
Фигня в том что функция пишущая в стрим всякую фигню flush не делает, а посему хотелось бы повлиять на размер буфера, что бы вывод в лог происходил почаще.
Как это сделать у boost::iostreams::stream Я пока найти не могу.

Засим кланяюсь. Спасибо за ответы.
Re: boost::iostreams пару вопросов
От: silart  
Дата: 11.07.11 09:22
Оценка:
Добрый день!

Я тоже пытаюсь реализовать что-то похожее. Проблема в том, как сделать чтобы не было буферизации?
Нужно чтобы любые операции чтения/записи сразу же отражались в памяти.

Вот код из примера:

   template<typename T>
    class memory_iodevice
    {
    public:
        typedef typename std::vector<T>::value_type    char_type;
        typedef typename std::vector<T>::size_type    size_type;
        typedef io::seekable_device_tag                category;

    private:
        std::vector<T>& m_container;
        size_type        m_pos;

    private:
        memory_iodevice operator=(const memory_iodevice&);

    public:
        memory_iodevice(std::vector<T>& container)
            : m_container(container), m_pos(0)
        {}

        std::streamsize read(char_type* s, std::streamsize n)
        {
            using namespace std;
            std::streamsize amt = 
                static_cast<std::streamsize>(m_container.size() - m_pos);
            std::streamsize result = (min)(n, amt);
            if (result != 0) {
                std::copy( m_container.begin() + m_pos,
                    m_container.begin() + m_pos + result,
                    s );
                m_pos += result;
                return result;
            } else {
                return -1; // EOF
            }
        }

        std::streamsize write(const char_type* s, std::streamsize n)
        {
            using namespace std;
            std::streamsize result = 0;
            if (m_pos != m_container.size()) {
                std::streamsize amt =
                    static_cast<std::streamsize>(m_container.size() - m_pos);
                result = (min)(n, amt);
                std::copy(s, s + result, m_container.begin() + m_pos);
                m_pos += result;
            }
            if (result < n) {
                m_container.insert(m_container.end(), s, s + n);
                m_pos = m_container.size();
            }
            return n;
        }

        std::streampos seek(io::stream_offset off, std::ios_base::seekdir way)
        {
            using namespace std;
            using namespace boost;
            using namespace io;

            try
            {
                // Determine new value of m_pos
                stream_offset next;
                if (way == BOOST_IOS::beg)
                {
                    next = off;
                } else
                if (way == BOOST_IOS::cur)
                {
                    next = m_pos + off;
                } else
                if (way == BOOST_IOS::end)
                {
                    next = m_container.size() + off;
                } else
                {
                    ML_THROW("bad seek direction");
                }

                // Check for errors
                if (next < 0 || next > m_container.size())
                    ML_THROW("bad seek offset");

                m_pos = numeric_cast<size_type>(next);
            }
            catch (bad_numeric_cast& e)
            {
                ML_THROW(e.what());
            }

            return m_pos;
        }
    };


Пробовал менять category:

struct custom_category : io::seekable_device_tag, io::direct_tag { };
typedef custom_category                category;


Ничего не получается. Компилятор ругается.

Каким образом можно сделать потоковый буфер БЕЗ БУФЕРИЗАЦИИ?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.