Есть некоторая функция принимающая на вход
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 Я пока найти не могу.
Засим кланяюсь. Спасибо за ответы.
Добрый день!
Я тоже пытаюсь реализовать что-то похожее. Проблема в том, как сделать чтобы не было буферизации?
Нужно чтобы любые операции чтения/записи сразу же отражались в памяти.
Вот код из примера:
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;
Ничего не получается. Компилятор ругается.
Каким образом можно сделать потоковый буфер БЕЗ БУФЕРИЗАЦИИ?