Search code examples
c++istream

C++; mirror and pass through from std::basic_istream<>?


GIVEN:

A class MyStream derived of std::basic_istream<> contains a pointer subject to a std::basic_istream<> object. It shall respond to tellg() and read() with modified content from the corresponding responses of subject.

template <class T> MyStream :
   public std::basic_istream<typename T::char_type, typename T::traits_type> {

   std::basic::istream<...>*   subject;

   ...
};

PROBLEM: The functions tellg(), seekg() and read() as well as the status-flag functions are not virtual.

QUESTION: How can a MyStream object pass tell, seek, and read to subject, forward the response to the caller and modifiy the status flags so that they correspond to the flags of subject?


Solution

  • Use something like this:

    template <typename T> struct MyStream : public std::basic_istream<typename T::char_type, typename T::traits_type> {
       struct rdbuf_impl : public std::basic_streambuf<typename T::char_type, typename T::traits_type> {
           // overwrite what you need
           std::basic::istream<...>* subject;
    
           // for tellg passthru (an example)
           pos_type seekoff( off_type off, std::ios_base::seekdir dir,
                          std::ios_base::openmode which = ios_base::in | ios_base::out ) overwrite {
               return subject->pubseekoff(off, dir, which);
           }
       };
       MyStream(std::basic::istream<...>* subject) {
           auto v = new rdbuf_impl(subject);
           rdbuf(v); // set associated stream buffer 'v' in 'this'.
       }
    };
    

    EDIT: Let's consider tellg method. Looking at definition of class basic_istream::tellg (https://en.cppreference.com/w/cpp/io/basic_istream/tellg) - it is written, that tellg will call rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in). Documentation for basic_streambuf::pubseekof (https://en.cppreference.com/w/cpp/io/basic_streambuf/pubseekoff) mentions, that it will call seekoff(off, dir, which). seekoff is virtual in basic_streambuf class and you can overwrite it.