Здравствуйте paul_shmakov, Вы писали:
PS>Как можно перегрузить streambuf для ofstream для модификации содержимого буфера при фактической записи содержимого в файл? В первую очередь интересует подпечатывание даты в начале новой строки, т.е. после выполнения операции:
PS> s << "Some string\n" << "Another string\n" << flush;
PS>В файле должно оказаться такое содержимое:
PS>[Дата] Some string
PS>[Дата] Another string
Надо унаследовать свой класс, скажем LogBuf (;-)), от std::streambuf и подменить его метод
overflow, реализовав в нем необходимую семантику. В данном случае эффективнее всего будет скопировать последовательность [pbase(); pptr()) в свою последовательность, вставляя "[Дата] " где нужно. Потом надо переадресовать вызов в std::filebuf::sputn(), дав в качестве аргументов параметры измененной последовательности:
class LogBuf : public std::streambuf
{
public:
void open( . . . )
{
m_file.open( . . . );
}
. . .
protected:
virtual int_type overflow(int_type c = traits::eof())
{
// ...
m_file.sputn(&m_seq[0], m_seq.size());
return traits::not_eof(c);
}
private:
std::vector<char> m_seq;
std::filebuf m_file;
};
Кроме того, для полнофункциональной работы твоего буфера надо будет переопределить функции
underflow (если буфер предназначен для работы в режиме чтения),
seekoff,
seekpos (если хочешь, чтобы поток, проинициализированный твоим буфером поддерживал seek),
sync и т.д., согласно документации.
Теперь осталось подменить потоку его буфер на твой. Если тебе не надо, чтобы поток был именно std::ofstream, просто передавай в конструктор std::ostream свой буфер, в противном случае надо будет вызывать std::
ostream::rdbuf, передавая в качестве аргумента свой LogBuf.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен