⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 specializer.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
📖 第 1 页 / 共 2 页
字号:
}voidSpecializer::do_simple_action(SpecializedClass &spc){  CxxFunction *simple_action = spc.cxxc->find("simple_action");  assert(simple_action);  simple_action->kill();  spc.cxxc->defun    (CxxFunction("smaction", false, "inline Packet *", simple_action->args(),		 simple_action->body(), simple_action->clean_body()));  spc.cxxc->defun    (CxxFunction("push", false, "void", "(int, Packet *p)",		 "\n  if (Packet *q = smaction(p))\n\    output_push(0, q);\n", ""));  spc.cxxc->defun    (CxxFunction("pull", false, "Packet *", "(int)",		 "\n  Packet *p = input_pull(0);\n\  return (p ? smaction(p) : 0);\n", ""));  spc.cxxc->find("output_push")->unkill();  spc.cxxc->find("input_pull")->unkill();}inline const String &Specializer::enew_cxx_type(int i) const{  int j = _specialize[i];  return _specials[j].cxx_name;}voidSpecializer::create_connector_methods(SpecializedClass &spc){  assert(spc.cxxc);  int eindex = spc.eindex;  CxxClass *cxxc = spc.cxxc;    // create mangled names of attached push and pull functions  const Vector<ConnectionT> &conn = _router->connections();  int nhook = _router->nconnections();  Vector<String> input_class(_ninputs[eindex], String());  Vector<String> output_class(_noutputs[eindex], String());  Vector<int> input_port(_ninputs[eindex], -1);  Vector<int> output_port(_noutputs[eindex], -1);  for (int i = 0; i < nhook; i++) {    if (conn[i].from_eindex() == eindex) {      output_class[conn[i].from_port()] = enew_cxx_type(conn[i].to_eindex());      output_port[conn[i].from_port()] = conn[i].to_port();    }    if (conn[i].to_eindex() == eindex) {      input_class[conn[i].to_port()] = enew_cxx_type(conn[i].from_eindex());      input_port[conn[i].to_port()] = conn[i].from_port();    }  }  // create input_pull  if (cxxc->find("input_pull")->alive()) {    StringAccum sa;    Vector<int> range1, range2;    for (int i = 0; i < _ninputs[eindex]; i++)      if (i > 0 && input_class[i] == input_class[i-1]	  && input_port[i] == input_port[i-1])	range2.back() = i;      else {	range1.push_back(i);	range2.push_back(i);      }    for (int i = 0; i < range1.size(); i++) {      int r1 = range1[i], r2 = range2[i];      if (!input_class[r1])	continue;      sa << "\n  ";      if (r1 == r2)	sa << "if (i == " << r1 << ") ";      else	sa << "if (i >= " << r1 << " && i <= " << r2 << ") ";      sa << "return ((" << input_class[r1] << " *)input(i).element())->"	 << input_class[r1] << "::pull(" << input_port[r1] << ");";    }    sa << "\n  return input(i).pull();\n";    cxxc->find("input_pull")->set_body(sa.take_string());  }  // create output_push  if (cxxc->find("output_push")->alive()) {    StringAccum sa;    Vector<int> range1, range2;    for (int i = 0; i < _noutputs[eindex]; i++)      if (i > 0 && output_class[i] == output_class[i-1]	  && output_port[i] == output_port[i-1])	range2.back() = i;      else {	range1.push_back(i);	range2.push_back(i);      }    for (int i = 0; i < range1.size(); i++) {      int r1 = range1[i], r2 = range2[i];      if (!output_class[r1])	continue;      sa << "\n  ";      if (r1 == r2)	sa << "if (i == " << r1 << ") ";      else	sa << "if (i >= " << r1 << " && i <= " << r2 << ") ";      sa << "{ ((" << output_class[r1] << " *)output(i).element())->"	 << output_class[r1] << "::push(" << output_port[r1]	 << ", p); return; }";    }    sa << "\n  output(i).push(p);\n";    cxxc->find("output_push")->set_body(sa.take_string());        sa.clear();    sa << "\n  if (i < " << _noutputs[eindex] << ")\n    output_push(i, p);\n";    sa << "  else\n    p->kill();\n";    cxxc->find("output_push_checked")->set_body(sa.take_string());  }}voidSpecializer::specialize(const Signatures &sigs, ErrorHandler *errh){  // decide what is to be specialized  _specialize = sigs.signature_ids();  SpecializedClass spc;  spc.eindex = SPCE_NOT_DONE;  _specials.assign(sigs.nsignatures(), spc);  _specials[0].eindex = SPCE_NOT_SPECIAL;  for (int i = 0; i < _nelements; i++)    check_specialize(i, errh);  // actually do the work  for (int s = 0; s < _specials.size(); s++) {    if (create_class(_specials[s]) && _specials[s].cxxc->find("simple_action"))      do_simple_action(_specials[s]);  }  for (int s = 0; s < _specials.size(); s++)    if (_specials[s].special())      create_connector_methods(_specials[s]);}voidSpecializer::fix_elements(){  for (int i = 0; i < _nelements; i++) {    SpecializedClass &spc = _specials[ _specialize[i] ];    if (spc.special())      _router->element(i)->set_type(ElementClassT::base_type(spc.click_name));  }}voidSpecializer::output_includes(ElementTypeInfo &eti, StringAccum &out){  // don't write includes twice for the same class  if (eti.wrote_includes)    return;    // must massage includes.  // we may have something like '#include "element.hh"', relying on the  // assumption that we are compiling 'element.cc'. must transform this  // to '#include "path/to/element.hh"'.  // XXX this is probably not the best way to do this  const String &includes = eti.includes;  const char *s = includes.data();  int len = includes.length();  // skip past '#ifndef X\n#define X' (sort of)  int p = 0;  while (p < len && isspace(s[p]))    p++;  if (p + 7 < len && strncmp(s + p, "#ifndef", 7) == 0) {    int next = p + 7;    for (; next < len && s[next] != '\n'; next++)      /* nada */;    if (next + 8 < len && strncmp(s + next + 1, "#define", 7) == 0) {      for (p = next + 8; p < len && s[p] != '\n'; p++)	/* nada */;    }  }  // now collect includes  while (p < len) {    int start = p;    int p2 = p;    while (p2 < len && s[p2] != '\n' && s[p2] != '\r')      p2++;    while (p < p2 && isspace(s[p]))      p++;    if (p < p2 && s[p] == '#') {      // we have a preprocessing directive!            // skip space after '#'      for (p++; p < p2 && isspace(s[p]); p++)	/* nada */;      // check for '#include'      if (p + 7 < p2 && strncmp(s+p, "include", 7) == 0) {		// find what is "#include"d	for (p += 7; p < p2 && isspace(s[p]); p++)	  /* nada */;	// interested in "user includes", not <system includes>	if (p < p2 && s[p] == '\"') {	  int left = p + 1;	  for (p++; p < p2 && s[p] != '\"'; p++)	    /* nada */;	  String include = includes.substring(left, p - left);	  int include_index = _header_file_map[include];	  if (include_index >= 0) {	    if (!_etinfo[include_index].found_header_file)	      _etinfo[include_index].locate_header_file(_router, ErrorHandler::default_handler());	    out << "#include \"" << _etinfo[include_index].found_header_file << "\"\n";	    p = p2 + 1;	    continue;		// don't use previous #include text	  }	}      }          }    out << includes.substring(start, p2 + 1 - start);    p = p2 + 1;  }  eti.wrote_includes = true;}voidSpecializer::output(StringAccum& out_header, StringAccum& out){  // output headers  for (int i = 0; i < _specials.size(); i++) {    SpecializedClass &spc = _specials[i];    if (spc.eindex >= 0) {      ElementTypeInfo &eti = etype_info(spc.eindex);      if (eti.found_header_file)	out_header << "#include \"" << eti.found_header_file << "\"\n";      if (spc.special())	spc.cxxc->header_text(out_header);    }  }  // output C++ code  for (int i = 0; i < _specials.size(); i++) {    SpecializedClass &spc = _specials[i];    if (spc.special()) {      ElementTypeInfo &eti = etype_info(spc.eindex);      output_includes(eti, out);      spc.cxxc->source_text(out);    }  }}voidSpecializer::output_package(const String &package_name, StringAccum &out, ErrorHandler* errh){    StringAccum elem2package, cmd_sa;    for (int i = 0; i < _specials.size(); i++)	if (_specials[i].special())	    elem2package <<  "-\t\"" << package_name << ".hh\"\t" << _specials[i].cxx_name << '-' << _specials[i].click_name << '\n';    String click_buildtool_prog = clickpath_find_file("click-buildtool", "bin", CLICK_BINDIR, errh);    cmd_sa << click_buildtool_prog << " elem2package " << package_name;    out << shell_command_output_string(cmd_sa.take_string(), elem2package.take_string(), errh);    }voidSpecializer::output_new_elementmap(const ElementMap &full_em, ElementMap &em,				   const String &filename, const String &requirements) const{    for (int i = 0; i < _specials.size(); i++)	if (_specials[i].special()) {	    Traits e = full_em.traits(_specials[i].old_click_name);	    e.name = _specials[i].click_name;	    e.cxx = _specials[i].cxx_name;	    e.header_file = filename + ".hh";	    e.source_file = filename + ".cc";	    e.requirements = requirements + _specials[i].old_click_name;	    e.provisions = String();	    em.add(e);	}}// Vector template instantiation#include <click/vector.cc>template class Vector<ElementTypeInfo>;template class Vector<SpecializedClass>;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -