void langbind::iostreamfilter( proc::ExecContext* execContext, const std::string& protocol, const std::string& proc, const std::string& ifl, std::size_t ib, const std::string& ofl, std::size_t ob, std::istream& is, std::ostream& os) { BufferStruct buf( ib, ob); const proc::ProcessorProviderInterface* provider = execContext->provider(); if (proc.size() == 0 || proc == "-") { LOG_TRACE << "Start executing filter"; Filter flt = getFilter( provider, ifl, ofl); if (!flt.inputfilter().get()) throw std::runtime_error( "input filter not found"); if (!flt.outputfilter().get()) throw std::runtime_error( "output filter not found"); flt.outputfilter()->setOutputChunkSize( buf.outsize); // ... no command specified -> we simply map the input through the // input/output filters specified: if (ifl.empty() && ofl.empty()) throw std::runtime_error( "argument for command, form or function not defined and no filter for processing specified"); const void* elem; int taglevel = 0; std::size_t elemsize; FilterBase::ElementType etype; while (taglevel >= 0) { if (!flt.inputfilter().get()->getNext( etype, elem, elemsize)) { if (flt.inputfilter()->state() == InputFilter::Open || flt.inputfilter()->state() == InputFilter::Start) { throw std::runtime_error( "filter not delivering final close tag"); } processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); continue; } if (etype == FilterBase::OpenTag) { taglevel++; } else if (etype == FilterBase::CloseTag) { taglevel--; } while (!flt.outputfilter().get()->print( etype, elem, elemsize)) { processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); } LOG_DATA << "[iostream filter] print " << FilterBase::elementTypeName(etype) << " '" << std::string( (const char*)elem, elemsize) << "'"; } while (!flt.outputfilter().get()->close()) { processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); } checkUnconsumedInput( is); writeOutput( os, *flt.outputfilter()); if (taglevel != -1) throw std::runtime_error( "tags not balanced"); return; } { if (proc[ proc.size()-1] == '~' || provider->hasCommand( proc)) { LOG_TRACE << "Start executing command '" << proc << "'"; cmdbind::ProtocolHandlerR protocolhnd; if (protocol.empty()) { protocolhnd.reset( new cmdbind::ContentOnlyProtocolHandler()); } else { protocolhnd.reset( provider->protocolHandler( protocol)); if (!protocolhnd.get()) throw std::runtime_error( std::string("protocol '") + protocol + "' is not defined"); } protocolhnd->setExecContext( execContext); if (proc[ proc.size()-1] == '~') { protocolhnd->setArgumentString( std::string( proc.c_str(), proc.size()-1)); } else { protocolhnd->setArgumentString( proc + "!"); } protocolhnd->setOutputBuffer( buf.outbuf, buf.outsize, 0); std::string lasterr; if (!processProtocolHandler( buf, protocolhnd.get(), is, os, lasterr)) { throw std::runtime_error( lasterr); } // Check if there is unconsumed input left (must not happen): checkUnconsumedInput( is); return; } } { const FormFunction* func = provider->formFunction( proc); if (func) { LOG_TRACE << "Start executing form function '" << proc << "'"; // ... command is the name of a form function we call directly // with the filter specified: Filter flt = getFilter( provider, ifl, ofl); if (!flt.inputfilter().get()) throw std::runtime_error( "input filter not found"); if (!flt.outputfilter().get()) throw std::runtime_error( "output filter not found"); flt.outputfilter()->setOutputChunkSize( buf.outsize); flt.inputfilter()->setValue( "empty", "false"); TypedInputFilterR inp( new TypingInputFilter( flt.inputfilter())); TypedOutputFilterR outp( new TypingOutputFilter( flt.outputfilter())); FormFunctionClosureR closure( func->createClosure()); closure->init( execContext, inp, serialize::Flags::ValidateAttributes); while (!closure->call()) processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); RedirectFilterClosure res( closure->result(), outp, true); while (!res.call()) processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); while (!flt.outputfilter()->close()) processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); writeOutput( os, *flt.outputfilter()); checkUnconsumedInput( is); return; } } { const types::FormDescription* st = provider->formDescription( proc); if (st) { LOG_TRACE << "Start mapping through form '" << proc << "'"; // ... command is the name a form description -> we simply map // the input with the input/output filters specified // through the form: Filter flt = getFilter( provider, ifl, ofl); if (!flt.inputfilter().get()) throw std::runtime_error( "input filter not found"); if (!flt.outputfilter().get()) throw std::runtime_error( "output filter not found"); flt.outputfilter()->setOutputChunkSize( buf.outsize); types::Form df( st); flt.inputfilter()->setValue( "empty", "false"); TypedInputFilterR inp( new TypingInputFilter( flt.inputfilter())); TypedOutputFilterR outp( new TypingOutputFilter( flt.outputfilter())); serialize::DDLStructParser closure( &df); closure.init( inp, serialize::Flags::ValidateAttributes); while (!closure.call()) processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); serialize::DDLStructSerializer res( &df); res.init( outp, serialize::Flags::None); while (!res.call()) processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); while (!flt.outputfilter()->close()) processIO( buf, flt.inputfilter().get(), flt.outputfilter().get(), is, os); writeOutput( os, *flt.outputfilter()); checkUnconsumedInput( is); return; } } throw std::runtime_error( std::string("identifier '") + proc + "' not defined as command, form or function"); }