//----------------------------------------------------------------------------------------- int precompfixt(XmlElement& xft, XmlElement& xf, ostream& outf, bool nounique) { int depth(1); XmlElement::XmlSet fldlist; xft.find("fix/fields/field", fldlist); xf.find("fix/fields/field", fldlist); if (!nounique) filter_unique(fldlist); XmlElement::XmlSet comlist, comlistfixt; Components components, componentsfixt; xft.find("fix/components/component", comlistfixt); xf.find("fix/components/component", comlist); load_components(comlistfixt, componentsfixt); load_components(comlist, components); outf << doctype << endl; outf << '<' << xft.GetTag(); output_attributes(xft, outf); outf << '>' << endl; const XmlElement *header(xft.find("fix/header")); if (header) process_messages(*header, componentsfixt, "header", 0, outf); const XmlElement *trailer(xft.find("fix/trailer")); if (trailer) process_messages(*trailer, componentsfixt, "trailer", 0, outf); outf << string(depth * 2, ' ') << "<messages>" << endl; XmlElement::XmlSet msglist; xft.find("fix/messages/message", msglist); for(XmlElement::XmlSet::const_iterator itr(msglist.begin()); itr != msglist.end(); ++itr) process_messages(**itr, componentsfixt, "message", depth, outf); msglist.clear(); xf.find("fix/messages/message", msglist); for(XmlElement::XmlSet::const_iterator itr(msglist.begin()); itr != msglist.end(); ++itr) process_messages(**itr, components, "message", depth, outf); outf << string(depth * 2, ' ') << "</messages>" << endl; process_fields(fldlist, depth, outf, false); dump_components(components, outf); outf << "</" << xft.GetTag() << '>' << endl; return 0; }
//----------------------------------------------------------------------------------------- void load_components(const XmlElement::XmlSet& comlist, Components& components) { for(XmlElement::XmlSet::const_iterator itr(comlist.begin()); itr != comlist.end(); ++itr) { string name; if ((*itr)->GetAttr("name", name)) components.insert(Components::value_type(name, *itr)); } }
//------------------------------------------------------------------------------------------------- size_t Configuration::get_addresses(const XmlElement *from, vector<Poco::Net::SocketAddress>& target) const { string name; const XmlElement *which; if (from && from->GetAttr("server_group", name) && (which = find_server_group(name))) { XmlElement::XmlSet slist; if (which->find("server", slist)) for(XmlElement::XmlSet::const_iterator itr(slist.begin()); itr != slist.end(); ++itr) target.push_back(get_address(*itr)); return target.size(); } return 0; }
//----------------------------------------------------------------------------------------- int process_message_fields(const std::string& where, const XmlElement *xt, FieldTraits& fts, const FieldToNumMap& ftonSpec, FieldSpecMap& fspec, const Components& compon) { unsigned processed(0); XmlElement::XmlSet flist; if (xt->find(where, flist)) { for(XmlElement::XmlSet::const_iterator fitr(flist.begin()); fitr != flist.end(); ++fitr) { string fname, required; if ((*fitr)->GetAttr("name", fname) && (*fitr)->GetAttr("required", required)) { FieldToNumMap::const_iterator ftonItr(ftonSpec.find(fname)); FieldSpecMap::iterator fs_itr; if (ftonItr == ftonSpec.end() || (fs_itr = fspec.find(ftonItr->second)) == fspec.end()) { cerr << shortName << ':' << recover_line(**fitr) << ": error: Field element missing required attributes" << endl; ++glob_errors; continue; } string compname; unsigned compidx((*fitr)->GetAttr("component", compname) ? lookup_component(compon, compname) : 0); // add FieldTrait if (!fts.add(FieldTrait(fs_itr->first, fs_itr->second._ftype, (*fitr)->GetSubIdx(), required == "Y", false, compidx))) { if (!nowarn) cerr << shortName << ':' << recover_line(**fitr) << ": warning: Could not add trait object '" << fname << "' (duplicate ?)" << endl; ++glob_warnings; } else { process_special_traits(fs_itr->first, fts); ++processed; fs_itr->second.set_used(); } } else { cerr << shortName << ':' << recover_line(**fitr) << ": error: Field element missing required attributes" << endl; ++glob_errors; } } } return processed; }
//----------------------------------------------------------------------------------------- void filter_unique(XmlElement::XmlSet& fldlist) { typedef map<string, const XmlElement *> UniqueFieldMap; UniqueFieldMap ufm; unsigned dupls(0); for(XmlElement::XmlSet::const_iterator itr(fldlist.begin()); itr != fldlist.end(); ++itr) { string name; (*itr)->GetAttr("name", name); if (!ufm.insert(UniqueFieldMap::value_type(name, *itr)).second) ++dupls; // cerr << "Duplicate field: " << name << endl; } fldlist.clear(); for(UniqueFieldMap::const_iterator itr(ufm.begin()); itr != ufm.end(); ++itr) fldlist.insert(itr->second); }
/*! Load a repeating group into a supplied map. \param tag the tag to find \param map_name the target map \param is_session if true, special case for session map \return the number of elements inserted */ unsigned load_map(const std::string& tag, ConfigMap& map_name, const bool is_session=false) { XmlElement::XmlSet slist; if (_root->find(tag, slist)) { for(XmlElement::XmlSet::const_iterator itr(slist.begin()); itr != slist.end(); ++itr) { std::string name; if ((*itr)->GetAttr("name", name) && is_session ? (*itr)->FindAttr("active", false) : true) { map_name.insert(ConfigMap::value_type(name, *itr)); if (is_session) _allsessions.push_back(*itr); } } } return map_name.size(); }
//----------------------------------------------------------------------------------------- void process_fields(const XmlElement::XmlSet& fldlist, const int depth, ostream& outf, bool required) { outf << string(depth * 2, ' ') << "<fields>" << endl; for(XmlElement::XmlSet::const_iterator itr(fldlist.begin()); itr != fldlist.end(); ++itr) { outf << string((depth + 1) * 2, ' ') << "<field"; output_attributes(**itr, outf, required); if ((*itr)->GetChildCnt()) { outf << '>' << endl; for(XmlElement::XmlSet::const_iterator fitr((*itr)->begin()); fitr != (*itr)->end(); ++fitr) { outf << string((depth + 2) * 2, ' ') << '<' << (*fitr)->GetTag(); output_attributes(**fitr, outf, required); outf << "/>" << endl; } outf << string((depth + 1) * 2, ' ') << "</field>" << endl; } else outf << "/>" << endl; } outf << string(depth * 2, ' ') << "</fields>" << endl; }