stream switch

Discussion in 'C++' started by Gabriel Schreiber, Sep 9, 2003.

  1. 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::eek:stream. (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 /"\
    \ / 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.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Gabriel Schreiber, Sep 9, 2003
    #1
    1. Advertising

  2. Gabriel Schreiber

    tom_usenet Guest

    On Tue, 09 Sep 2003 14:22:27 +0200, Gabriel Schreiber
    <-aachen.de> wrote:

    >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::eek:stream. (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?


    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_traits<CharT> >
    class basic_multioutputbuf: public std::basic_streambuf<CharT, Traits>
    {

    public:
    typedef std::basic_streambuf<CharT, Traits> streambuf_t;
    typedef CharT char_type;
    typedef Traits traits_type;
    typedef typename traits_type::int_type int_type;
    typedef typename traits_type::pos_type pos_type;
    typedef typename traits_type::eek:ff_type off_type;

    void add_buf(streambuf_t* buf)
    {
    m_bufs.push_back(buf);
    }

    protected:

    int_type overflow(int_type c)
    {
    int_type result = traits_type::not_eof(c);
    if (traits_type::eq_int_type(traits_type::eof(), c))
    {
    return result;
    }
    char_type cc = traits_type::to_char_type(c);
    for (vector_t::iterator i = m_bufs.begin(), end = m_bufs.end();
    i != end; ++i)
    {
    int_type example = (*i)->sputc(cc);
    if (traits_type::eq_int_type(traits_type::eof(), example))
    {
    result = traits_type::eof();
    }
    }
    return result;
    }

    int sync()
    {
    int result = 0;
    for (vector_t::iterator 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_traits<CharT> >
    class basic_multioutputostream: public std::basic_ostream<CharT,
    Traits>
    {
    public:
    basic_multioutputostream()
    :std::basic_ostream<CharT, Traits>(0)
    {
    this->rdbuf(&m_streambuf);
    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_multioutputbuf<CharT, Traits> m_streambuf;
    };

    typedef basic_multioutputbuf<char> multioutputbuf;
    typedef basic_multioutputbuf<wchar_t> wmultioutputbuf;
    typedef basic_multioutputostream<char> multioutputostream;
    typedef basic_multioutputostream<wchar_t> wmultioutputostream;

    #include <iostream>
    #include <fstream>

    int main()
    {
    std::eek:fstream ofs1("Test1.txt");
    std::eek:fstream ofs2("Test2.txt");
    multioutputostream os;
    os.add(std::cout);
    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";
    }
    tom_usenet, Sep 9, 2003
    #2
    1. Advertising

  3. tom_usenet wrote:
    >
    > >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::eek:stream. (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?

    >
    > 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
    >


    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
    Gabriel Schreiber, Sep 9, 2003
    #3
  4. Gabriel Schreiber

    tom_usenet Guest

    On Tue, 09 Sep 2003 15:36:22 +0200, Gabriel Schreiber
    <-aachen.de> wrote:

    >tom_usenet wrote:
    >>
    >> >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::eek:stream. (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?

    >>
    >> 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
    >>

    >
    >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?


    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
    tom_usenet, Sep 9, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rasmusson, Lars
    Replies:
    1
    Views:
    754
    popov
    Apr 30, 2004
  2. Replies:
    9
    Views:
    629
    Alex Buell
    Apr 27, 2006
  3. Alexander Korsunsky

    get stream mode flags from an opened stream

    Alexander Korsunsky, Feb 17, 2007, in forum: C++
    Replies:
    1
    Views:
    452
    John Harrison
    Feb 17, 2007
  4. dolphin
    Replies:
    6
    Views:
    556
    Thomas Fritsch
    Mar 18, 2007
  5. Switch Within A Switch

    , Apr 22, 2006, in forum: Javascript
    Replies:
    7
    Views:
    106
    Lasse Reichstein Nielsen
    Apr 22, 2006
Loading...

Share This Page