Boost logo

Boost :

From: christopher diggins (cdiggins_at_[hidden])
Date: 2005-01-09 12:25:00


> Hi Christopher,
>
> I don't have much time to write today but I'd like to make several
> observations
> about this discussion.
>
> It seems to me that what you are trying to achieve is something that is
> already
> well-supported by the iostreams library. The iostreams library offers
> users a
> number of different ways to write filters, with the understanding that
> some
> methods will be more efficient or convenient for a particular purpose than
> another.

Hi Jonathan,

Thanks for responding. I have now managed to get the iostreams library to do
what I wanted (see my code below). The only thing missing now is the ability
to chain sequences of filters.

> Given the above definition, if you write a class which derives from
> co_filter
> and override the pure virtual function do_filter, you can add it to the
> filtering streams from the iostreams library and it will work as you have
> described, if I understand you correctly.

Using what you provided, here is the code which enables us to use an
arbitrary procedure as an iostream filter:

typedef void(*procedure)();

class proc_as_filter : public co_filter<char> {
  public:
    proc_as_filter(procedure x) : proc(x) { }
    virtual void do_filter(
      basic_istream<char>& in,
      basic_ostream<char>& out)
    {
      streambuf* inbuf = cin.rdbuf();
      streambuf* outbuf = cout.rdbuf();
      cin.rdbuf(in.rdbuf());
      cout.rdbuf(out.rdbuf());
      proc();
      cin.rdbuf(inbuf);
      cout.rdbuf(outbuf);
    }
  private:
    procedure proc;
};

void ToUpperFilterFxn() {
  char ch;
  while (cin.get(ch)) {
    cout.put(toupper(ch));
  }
}

int main()
{
  string s = "hello jonathan\n";
  filtering_ostream out;
  out.push(proc_as_filter(ToUpperFilterFxn));
  out.push(cout);
  boost::io::copy(stringstream(s), out);
  return 0;
}

I compiled and successfuly ran this on Visual C++ 7.1. What are the chances
something like this could find its way into the iostreams library?

> However, I should be able to extend it so that if a chain contains both a
> source
> and a sink, boost::io::copy is invoked. E.g.,
>
> source() | filter1() | filter2() | filter3() | sink()
>
> would be equivalent to
>
> filtering_ostream out(filter1() | filter2() | filter3() | sink());
> boost::io::copy(source, out);
>
> If I can make this work, and there are no objections, I'll add it.

This is what I am ultimately striving for. Is there any reason why the
source() and sink() can not be assumed to be cin and cout respectively when
absent?

>> 7) allow threading of functions
>
> Do you mean this: support filters which think they are processing an
> entire
> stream at once, but really their threads are waiting on some
> syncronization
> object whenever there is no more input available, or output buffers are
> full?

What I want is to allow two proc_as_filter objects to be executed
simultaneously, so that this code:

proc_as_filter(Proc1) | proc_as_filter(Proc2)

Runs optimally on a multi-processor machine. I don't know how hard this is,
I am quite inexperienced in multithreaded code.

Christopher Diggins
http://www.cdiggins.com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk