> In order to wrap some complex shell program into C++ classes and/or
> functions I need to do the following:
> 1. Creating/Manipulating some input data stream
> 2. Piping this stream to the program (as it's stdin)
> 3. Processing the output (i.e. parsing stdout into a struct/class
> The * way to do this would be to write the input data of the program
> in some (temporary) file, using system() or popen() and parsing the
> output file. This would imply to create at least one temporary file.
> A second posibility would be to use the GNU C++ Iostream Library's
> procbuf class. To my experience this works for either the input stream
> or the output stream, but not both of them.
> Is there any solution (preferably using iostream/ostream-like classes
> and C++ streambuffers) to this problem?
> Thanks in advance,
> Reinhard
It should be possible to define your own target for the standard out-object.
i think it would look like this:
template<class charT, class Traits>
basic_istream<charT, Traits>& operator >>
(basic_istream<charT, Traits >& is, UserDefinedType& x)
{
ios_base::iostate err = 0;
try {
typename basic_istream<charT, Traits>::sentry ipfx(is);
if(ipfx)
{
// Do whatever has to be done!
// Typically you will access the stream's locale or buffer.
// Don't call stream member functions here in MT environments!
// Add state bits to the err variable if necessary, e.g.
// if (...) err |= ios_base::failbit;
}
Quote:} // try
catch(...) //1
{
bool flag = FALSE;
try { is.setstate(ios_base::failbit); } //2
catch( ios_base::failure ) { flag= TRUE; } //3
if ( flag ) throw; //4
Quote:}
if ( err ) is.setstate(err); //5
return is;
Quote:}
Similarly, the pattern for the inserter looks like this:
template<class charT, class Traits>
basic_ostream<charT, Traits>& operator <<
(basic_ostream<charT, Traits >& os, const UserDefinedType& x)
{
ios_base::iostate err = 0;
try {
typename basic_ostream<charT, Traits>::sentry opfx(os);
if(opfx)
{
// Do whatever has to be done!
// Typically you will access the stream's locale or buffer.
// Don't call stream member functions here in MT environments!
// Add state bits to the err variable if necessary, e.g.
// if (...) err |= ios_base::failbit;
// Reset the field width after usage, i.e.
// os.width(0);
}
Quote:} //try
catch(...)
{
bool flag = FALSE;
try { os.setstate(ios_base::failbit); }
catch( ios_base::failure ) { flag= TRUE; }
if ( flag ) throw;
Quote:}
if ( err ) os.setstate(err);
return os;
Quote:}
Greetings,
Stefan Depenbrock