// -*- c-basic-offset: 4 -*-
#ifndef CLICK_PROCESSINGT_HH
#define CLICK_PROCESSINGT_HH
#include "routert.hh"
class ElementMap;
class Bitvector;
class ProcessingT { public:
enum ProcessingCode { VAGNOSTIC = 0, VPUSH = 1, VPULL = 2 };
static const char processing_letters[];
ProcessingT();
ProcessingT(const RouterT *, ErrorHandler *);
ProcessingT(const RouterT *, ElementMap *, ErrorHandler *);
ProcessingT(const RouterT *, ElementMap *, bool flatten, ErrorHandler *);
int reset(const RouterT *, ElementMap *, bool flatten, ErrorHandler *);
void resolve_agnostics(); // change remaining AGNOSTICs to PUSH
int nelements() const { return _input_pidx.size() - 1; }
int ninput_pidx() const { return _input_pidx.back(); }
int noutput_pidx() const { return _output_pidx.back(); }
int input_pidx(const ConnectionT &) const;
int output_pidx(const ConnectionT &) const;
int input_pidx(const PortT &) const;
int output_pidx(const PortT &) const;
int input_pidx(int ei, int p = 0) const { return _input_pidx[ei]+p; }
int output_pidx(int ei, int p = 0) const { return _output_pidx[ei]+p; }
PortT input_port(int pidx) const;
PortT output_port(int pidx) const;
int input_processing(const PortT &) const;
int output_processing(const PortT &) const;
int input_processing(int ei, int p) const;
int output_processing(int ei, int p) const;
bool input_is_pull(int ei, int p) const;
bool output_is_push(int ei, int p) const;
const PortT &input_connection(int ei, int p) const;
const PortT &output_connection(int ei, int p) const;
bool same_processing(int, int) const;
String processing_code(const ElementT *) const;
static int forward_flow(const String &code, int input_port, int noutputs, Bitvector *, ErrorHandler * = 0);
static int forward_flow(const PortT &, Bitvector *, ErrorHandler * = 0);
static int backward_flow(const String &code, int output_port, int ninputs, Bitvector *, ErrorHandler * = 0);
static int backward_flow(const PortT &, Bitvector *, ErrorHandler * = 0);
void set_connected_inputs(const Bitvector &, Bitvector &) const;
void set_connected_outputs(const Bitvector &, Bitvector &) const;
void set_connected_inputs(const PortT &, Bitvector &) const;
void set_connected_outputs(const PortT &, Bitvector &) const;
void set_flowed_inputs(const Bitvector &, Bitvector &, ErrorHandler* = 0) const;
void set_flowed_outputs(const Bitvector &, Bitvector &, ErrorHandler* = 0) const;
void forward_reachable_inputs(Bitvector &, ErrorHandler * = 0) const;
String compound_processing_code() const;
String compound_flow_code(ErrorHandler * = 0) const;
private:
const RouterT *_router;
Vector<int> _input_pidx;
Vector<int> _output_pidx;
Vector<const ElementT *> _input_elt;
Vector<const ElementT *> _output_elt;
Vector<int> _input_processing;
Vector<int> _output_processing;
Vector<PortT> _connected_input;
Vector<PortT> _connected_output;
void create_pidx(ErrorHandler *);
void initial_processing_for(int, ErrorHandler *);
void initial_processing(ErrorHandler *);
void processing_error(const ConnectionT &, int, ErrorHandler *);
void check_processing(ErrorHandler *);
void check_connections(ErrorHandler *);
};
inline int
ProcessingT::input_pidx(const PortT &h) const
{
assert(h.router() == _router);
return input_pidx(h.eindex(), h.port);
}
inline int
ProcessingT::output_pidx(const PortT &h) const
{
assert(h.router() == _router);
return output_pidx(h.eindex(), h.port);
}
inline int
ProcessingT::input_pidx(const ConnectionT &c) const
{
return input_pidx(c.to());
}
inline int
ProcessingT::output_pidx(const ConnectionT &c) const
{
return output_pidx(c.from());
}
inline PortT
ProcessingT::input_port(int pidx) const
{
const ElementT *e = _input_elt[pidx];
return PortT(const_cast<ElementT *>(e), pidx - _input_pidx[e->eindex()]);
}
inline PortT
ProcessingT::output_port(int pidx) const
{
const ElementT *e = _output_elt[pidx];
return PortT(const_cast<ElementT *>(e), pidx - _output_pidx[e->eindex()]);
}
inline int
ProcessingT::input_processing(const PortT &h) const
{
return _input_processing[input_pidx(h)];
}
inline int
ProcessingT::output_processing(const PortT &h) const
{
return _output_processing[output_pidx(h)];
}
inline int
ProcessingT::input_processing(int i, int p) const
{
return _input_processing[input_pidx(i, p)];
}
inline int
ProcessingT::output_processing(int i, int p) const
{
return _output_processing[output_pidx(i, p)];
}
inline bool
ProcessingT::input_is_pull(int i, int p) const
{
return input_processing(i, p) == VPULL;
}
inline bool
ProcessingT::output_is_push(int i, int p) const
{
return output_processing(i, p) == VPUSH;
}
inline const PortT &
ProcessingT::input_connection(int i, int p) const
{
return _connected_input[input_pidx(i, p)];
}
inline const PortT &
ProcessingT::output_connection(int i, int p) const
{
return _connected_output[output_pidx(i, p)];
}
inline int
ProcessingT::forward_flow(const PortT &p, Bitvector *bv, ErrorHandler *errh)
{
return forward_flow(p.element->type()->flow_code(), p.port, p.element->noutputs(), bv, errh);
}
inline int
ProcessingT::backward_flow(const PortT &p, Bitvector *bv, ErrorHandler *errh)
{
return backward_flow(p.element->type()->flow_code(), p.port, p.element->ninputs(), bv, errh);
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1