stream switch

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gabriel Schreiber

    stream switch

    Hy

    I need some help on this problem:

    I want to send some output to a number of streams. So I need an object,
    that behaves (or is) like an std::ostream. (additional wish: the object
    is an ostream or derived from an ostream.) And I need the data you give
    to the ostream-like object to be written to a varying number of
    ostreams.

    Is it possible to do this with some magic with the streambuffers, or do
    I have to write my own class?

    TIA
    Gabriel

    ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~
    Gabriel Akira Schreiber /"\
    gabriel.schreib er@gmx.net \ / ASCII Ribbon Campaign
    X against HTML eMail &
    / \ gratuitous graphics
    ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~
    Wenn sie dich dazu bringen, falsche Fragen zu stellen,
    müssen sie sich um die Antworten keine Sorgen machen.
    ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~
  • tom_usenet

    #2
    Re: stream switch

    On Tue, 09 Sep 2003 14:22:27 +0200, Gabriel Schreiber
    <schreiber@ient .rwth-aachen.de> wrote:
    [color=blue]
    >Hy =
    >
    >
    >I need some help on this problem:
    >
    >I want to send some output to a number of streams. So I need an object,
    >that behaves (or is) like an std::ostream. (additional wish: the object
    >is an ostream or derived from an ostream.) And I need the data you give
    >to the ostream-like object to be written to a varying number of
    >ostreams.
    >
    >Is it possible to do this with some magic with the streambuffers, or do
    >I have to write my own class?[/color]

    You need some magic streambufs. The heiroglyphics come from templating
    it on character and traits type - without the template stuff (e.g.
    char only) it is much simpler.

    Obviously you can easily add more control over the list of buffers
    (even expose the vector member) if required.

    Tom


    #include <streambuf>
    #include <vector>

    template <class CharT, class Traits = std::char_trait s<CharT> >
    class basic_multioutp utbuf: public std::basic_stre ambuf<CharT, Traits>
    {

    public:
    typedef std::basic_stre ambuf<CharT, Traits> streambuf_t;
    typedef CharT char_type;
    typedef Traits traits_type;
    typedef typename traits_type::in t_type int_type;
    typedef typename traits_type::po s_type pos_type;
    typedef typename traits_type::of f_type off_type;

    void add_buf(streamb uf_t* buf)
    {
    m_bufs.push_bac k(buf);
    }

    protected:

    int_type overflow(int_ty pe c)
    {
    int_type result = traits_type::no t_eof(c);
    if (traits_type::e q_int_type(trai ts_type::eof(), c))
    {
    return result;
    }
    char_type cc = traits_type::to _char_type(c);
    for (vector_t::iter ator i = m_bufs.begin(), end = m_bufs.end();
    i != end; ++i)
    {
    int_type example = (*i)->sputc(cc);
    if (traits_type::e q_int_type(trai ts_type::eof(), example))
    {
    result = traits_type::eo f();
    }
    }
    return result;
    }

    int sync()
    {
    int result = 0;
    for (vector_t::iter ator i = m_bufs.begin(), end = m_bufs.end();
    i != end; ++i)
    {
    int example = (*i)->pubsync();
    if (example == -1)
    {
    result = -1;
    }
    }
    return result;
    }

    private:
    typedef std::vector<std ::streambuf*> vector_t;
    vector_t m_bufs;
    };

    template <class CharT, class Traits = std::char_trait s<CharT> >
    class basic_multioutp utostream: public std::basic_ostr eam<CharT,
    Traits>
    {
    public:
    basic_multioutp utostream()
    :std::basic_ost ream<CharT, Traits>(0)
    {
    this->rdbuf(&m_strea mbuf);
    this->clear();
    //that was all in case the ostream constructor
    //does anything odd with the streambuf argument.
    //The "this" bit was to make the names dependent.
    }

    void add(std::basic_ streambuf<CharT , Traits>* buf)
    {
    m_streambuf.add _buf(buf);
    }

    void add(std::basic_ ostream<CharT, Traits>& os)
    {
    m_streambuf.add _buf(os.rdbuf() );
    }

    private:
    basic_multioutp utbuf<CharT, Traits> m_streambuf;
    };

    typedef basic_multioutp utbuf<char> multioutputbuf;
    typedef basic_multioutp utbuf<wchar_t> wmultioutputbuf ;
    typedef basic_multioutp utostream<char> multioutputostr eam;
    typedef basic_multioutp utostream<wchar _t> wmultioutputost ream;

    #include <iostream>
    #include <fstream>

    int main()
    {
    std::ofstream ofs1("Test1.txt ");
    std::ofstream ofs2("Test2.txt ");
    multioutputostr eam os;
    os.add(std::cou t);
    os.add(ofs1);
    os.add(ofs2);

    os << "This should go all over the place!\n";
    os << std::flush << "That was a quick flush test.\n";
    }

    Comment

    • Gabriel Schreiber

      #3
      Re: stream switch

      tom_usenet wrote:[color=blue]
      >[color=green]
      > >I need some help on this problem:
      > >
      > >I want to send some output to a number of streams. So I need an object,
      > >that behaves (or is) like an std::ostream. (additional wish: the object
      > >is an ostream or derived from an ostream.) And I need the data you give
      > >to the ostream-like object to be written to a varying number of
      > >ostreams.
      > >
      > >Is it possible to do this with some magic with the streambuffers, or do
      > >I have to write my own class?[/color]
      >
      > You need some magic streambufs. The heiroglyphics come from templating
      > it on character and traits type - without the template stuff (e.g.
      > char only) it is much simpler.
      >
      > Obviously you can easily add more control over the list of buffers
      > (even expose the vector member) if required.
      >
      > Tom
      >[/color]

      Tanx very much, Tom. This is exactly was I was thinking of...
      The templates do not make me headaches, but not knowing how a
      streambuffer really works somehow slowed the process of understanding
      the code down. Is that part of any library?

      Sincerely
      Gabriel

      // code starts here

      Comment

      • tom_usenet

        #4
        Re: stream switch

        On Tue, 09 Sep 2003 15:36:22 +0200, Gabriel Schreiber
        <schreiber@ient .rwth-aachen.de> wrote:
        [color=blue]
        >tom_usenet wrote:[color=green]
        >>[color=darkred]
        >> >I need some help on this problem:
        >> >
        >> >I want to send some output to a number of streams. So I need an object,
        >> >that behaves (or is) like an std::ostream. (additional wish: the object
        >> >is an ostream or derived from an ostream.) And I need the data you give
        >> >to the ostream-like object to be written to a varying number of
        >> >ostreams.
        >> >
        >> >Is it possible to do this with some magic with the streambuffers, or do
        >> >I have to write my own class?[/color]
        >>
        >> You need some magic streambufs. The heiroglyphics come from templating
        >> it on character and traits type - without the template stuff (e.g.
        >> char only) it is much simpler.
        >>
        >> Obviously you can easily add more control over the list of buffers
        >> (even expose the vector member) if required.
        >>
        >> Tom
        >>[/color]
        >
        >Tanx very much, Tom. This is exactly was I was thinking of...
        >The templates do not make me headaches, but not knowing how a
        >streambuffer really works somehow slowed the process of understanding
        >the code down. Is that part of any library?[/color]

        Sorry, not that I know of (I just wrote it off the top of my head).
        Such a thing (with buffering, etc. added) should probably be part of
        boost (www.boost.org).

        Tom

        Comment

        Working...