Re: Перегрузка streambuf
От: Павел Кузнецов  
Дата: 30.08.02 14:52
Оценка:
Здравствуйте 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.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.