#ifndef __XIOS_CGroupTemplate_impl__ #define __XIOS_CGroupTemplate_impl__ #include "xios_spl.hpp" #include "event_server.hpp" #include "object_template.hpp" #include "group_template.hpp" #include "context.hpp" #include "event_client.hpp" #include "context_client.hpp" #include "message.hpp" #include "type.hpp" #include "type_util.hpp" namespace xios { /// ////////////////////// Définitions ////////////////////// /// template CGroupTemplate::CGroupTemplate(void) : CObjectTemplate() //, V() , childMap(), childList() , groupMap(), groupList() { /* Ne rien faire de plus */ } template CGroupTemplate::CGroupTemplate(const StdString & id) : CObjectTemplate(id) //, V() , childMap(), childList() , groupMap(), groupList() { /* Ne rien faire de plus */ } template CGroupTemplate::~CGroupTemplate(void) { /* Ne rien faire de plus */ } ///-------------------------------------------------------------- /* template void CGroupTemplate::toBinary(StdOStream & os) const { SuperClass::toBinary(os); const StdSize grpnb = this->groupList.size(); const StdSize chdnb = this->childList.size(); ENodeType cenum = U::GetType(); ENodeType genum = V::GetType(); os.write (reinterpret_cast(&grpnb) , sizeof(StdSize)); os.write (reinterpret_cast(&chdnb) , sizeof(StdSize)); typename std::vector::const_iterator itg = this->groupList.begin(), endg = this->groupList.end(); typename std::vector::const_iterator itc = this->childList.begin(), endc = this->childList.end(); for (; itg != endg; itg++) { V* group = *itg; bool hid = group->hasId(); os.write (reinterpret_cast(&genum), sizeof(ENodeType)); os.write (reinterpret_cast(&hid), sizeof(bool)); if (hid) { const StdString & id = group->getId(); const StdSize size = id.size(); os.write (reinterpret_cast(&size), sizeof(StdSize)); os.write (id.data(), size * sizeof(char)); } group->toBinary(os); } for (; itc != endc; itc++) { U* child = *itc; bool hid = child->hasId(); os.write (reinterpret_cast(&cenum), sizeof(ENodeType)); os.write (reinterpret_cast(&hid), sizeof(bool)); if (hid) { const StdString & id = child->getId(); const StdSize size = id.size(); os.write (reinterpret_cast(&size), sizeof(StdSize)); os.write (id.data(), size * sizeof(char)); } child->toBinary(os); } } template void CGroupTemplate::fromBinary(StdIStream & is) { SuperClass::fromBinary(is); V* group_ptr = (this->hasId()) ? V::get(this->getId()) : V::get((V*)this); StdSize grpnb = 0; StdSize chdnb = 0; ENodeType renum = Unknown; is.read (reinterpret_cast(&grpnb), sizeof(StdSize)); is.read (reinterpret_cast(&chdnb), sizeof(StdSize)); for (StdSize i = 0; i < grpnb; i++) { bool hid = false; is.read (reinterpret_cast(&renum), sizeof(ENodeType)); is.read (reinterpret_cast(&hid), sizeof(bool)); if (renum != V::GetType()) ERROR("CGroupTemplate::fromBinary(StdIStream & is)", << "[ renum = " << renum << "] Bad type !"); if (hid) { StdSize size = 0; is.read (reinterpret_cast(&size), sizeof(StdSize)); StdString id(size, ' '); is.read (const_cast(id.data()), size * sizeof(char)); CGroupFactory::CreateGroup(group_ptr->getShared(), id)->fromBinary(is); } else { CGroupFactory::CreateGroup(group_ptr->getShared())->fromBinary(is); } } for (StdSize j = 0; j < chdnb; j++) { bool hid = false; is.read (reinterpret_cast(&renum), sizeof(ENodeType)); is.read (reinterpret_cast(&hid), sizeof(bool)); if (renum != U::GetType()) ERROR("CGroupTemplate::fromBinary(StdIStream & is)", << "[ renum = " << renum << "] Bad type !"); if (hid) { StdSize size = 0; is.read (reinterpret_cast(&size), sizeof(StdSize)); StdString id(size, ' '); is.read (const_cast(id.data()), size * sizeof(char)); CGroupFactory::CreateChild(group_ptr->getShared(), id)->fromBinary(is); } else { CGroupFactory::CreateChild(group_ptr->getShared())->fromBinary(is); } } } */ //-------------------------------------------------------------- template StdString CGroupTemplate::toString(void) const { StdOStringStream oss; StdString name = (this->getId().compare(V::GetDefName()) != 0) ? V::GetName() : V::GetDefName(); oss << "<" << name << " "; if (this->hasId() && (this->getId().compare(V::GetDefName()) != 0)) oss << " id=\"" << this->getId() << "\" "; if (this->hasChild()) { oss << SuperClassAttribute::toString() << ">" << std::endl; typename std::vector::const_iterator itg = this->groupList.begin(), endg = this->groupList.end(); typename std::vector::const_iterator itc = this->childList.begin(), endc = this->childList.end(); for (; itg != endg; itg++) { V* group = *itg; oss << *group << std::endl; } for (; itc != endc; itc++) { U* child = *itc; oss << *child << std::endl; } oss << ""; } else { oss << SuperClassAttribute::toString() << "/>"; } return (oss.str()); } template void CGroupTemplate::fromString(const StdString & str) { ERROR("CGroupTemplate::toString(void)", << "[ str = " << str << "] Not implemented yet !"); } //--------------------------------------------------------------- template StdString CGroupTemplate::GetName(void) { return (U::GetName().append("_group")); } template StdString CGroupTemplate::GetDefName(void) { return (U::GetName().append("_definition")); } //--------------------------------------------------------------- template const std::vector& CGroupTemplate::getChildList(void) const { return (this->childList); } //--------------------------------------------------------------- template const xios_map& CGroupTemplate::getGroupMap(void) const { return (this->groupMap); } //--------------------------------------------------------------- template bool CGroupTemplate::hasChild(void) const { return ((groupList.size() + childList.size()) > 0); } //--------------------------------------------------------------- template void CGroupTemplate::parse(xml::CXMLNode & node) { this->parse(node, true); } //--------------------------------------------------------------- template void CGroupTemplate::solveDescInheritance(bool apply, const CAttributeMap * const parent) { if (parent != NULL) SuperClassAttribute::setAttributes(parent, apply); typename std::vector::const_iterator itc = this->childList.begin(), endc = this->childList.end(); typename std::vector::const_iterator itg = this->groupList.begin(), endg = this->groupList.end(); for (; itc != endc; itc++) { U* child = *itc; child->solveDescInheritance(apply,this); } for (; itg != endg; itg++) { V* group = *itg; if (apply) group->solveRefInheritance(); group->solveDescInheritance(apply,this); } } //--------------------------------------------------------------- template void CGroupTemplate::getAllChildren(std::vector& allc) const { allc.insert (allc.end(), childList.begin(), childList.end()); typename std::vector::const_iterator itg = this->groupList.begin(), endg = this->groupList.end(); for (; itg != endg; itg++) { V* group = *itg; group->getAllChildren(allc); } } //--------------------------------------------------------------- template std::vector CGroupTemplate::getAllChildren(void) const { std::vector allc; this->getAllChildren(allc); return (allc); } //--------------------------------------------------------------- template void CGroupTemplate::solveRefInheritance(void) { /* Ne rien faire de plus */ } // template // bool CGroupTemplate::has(const string& id) // { // return CObjectFactory::HasObject(id) ; // } // template // boost::shared_ptr CGroupTemplate::get(const string& id) // { // return CObjectFactory::GetObject(id) ; // } // template // boost::shared_ptr CGroupTemplate::get() // { // return CObjectFactory::GetObject(this) ; // } // template // boost::shared_ptr CGroupTemplate::create(const string& id) // { // return CObjectFactory::CreateObject(id) ; // } ///-------------------------------------------------------------- template U* CGroupTemplate::createChild(const string& id) { return CGroupFactory::CreateChild(this->getShared(), id).get() ; } template void CGroupTemplate::addChild(U* child) { return CGroupFactory::AddChild(this->getShared(),child->getShared()) ; } template V* CGroupTemplate::createChildGroup(const string& id) { return CGroupFactory::CreateGroup(this->getShared(), id).get() ; } template void CGroupTemplate::addChildGroup(V* childGroup) { return CGroupFactory::AddGroup(this->getShared(), childGroup->getShared()) ; } template void CGroupTemplate::sendCreateChild(const string& id) { CContext* context=CContext::getCurrent() ; if (context->hasClient) // if (!context->hasServer ) { // Use correct context client to send message // CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client; int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; for (int i = 0; i < nbSrvPools; ++i) { CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client; CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ; if (contextClientTmp->isServerLeader()) { CMessage msg ; msg<getId() ; msg<& ranks = contextClientTmp->getRanksServerLeader(); for (std::list::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) event.push(*itRank,1,msg) ; contextClientTmp->sendEvent(event) ; } else contextClientTmp->sendEvent(event) ; } } } template void CGroupTemplate::sendCreateChild(const string& id, CContextClient* client) { CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ; if (client->isServerLeader()) { CMessage msg ; msg<getId() ; msg<& ranks = client->getRanksServerLeader(); for (std::list::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) event.push(*itRank,1,msg) ; client->sendEvent(event) ; } else client->sendEvent(event) ; } template void CGroupTemplate::sendCreateChildGroup(const string& id) { CContext* context=CContext::getCurrent() ; if (context->hasClient) { // Use correct context client to send message // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; for (int i = 0; i < nbSrvPools; ++i) { CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client; CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD_GROUP) ; if (contextClientTmp->isServerLeader()) { CMessage msg ; msg<getId() ; msg<& ranks = contextClientTmp->getRanksServerLeader(); for (std::list::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) event.push(*itRank,1,msg) ; contextClientTmp->sendEvent(event) ; } else contextClientTmp->sendEvent(event) ; } } } template void CGroupTemplate::recvCreateChild(CEventServer& event) { CBufferIn* buffer=event.subEvents.begin()->buffer; string id; *buffer>>id ; V::get(id)->recvCreateChild(*buffer) ; } template void CGroupTemplate::recvCreateChild(CBufferIn& buffer) { string id ; buffer>>id ; createChild(id) ; } template void CGroupTemplate::recvCreateChildGroup(CEventServer& event) { CBufferIn* buffer=event.subEvents.begin()->buffer; string id; *buffer>>id ; V::get(id)->recvCreateChildGroup(*buffer) ; } template void CGroupTemplate::recvCreateChildGroup(CBufferIn& buffer) { string id ; buffer>>id ; createChildGroup(id) ; } template bool CGroupTemplate::dispatchEvent(CEventServer& event) { if (CObjectTemplate::dispatchEvent(event)) return true ; else { switch(event.type) { case EVENT_ID_CREATE_CHILD : recvCreateChild(event) ; return true ; break ; case EVENT_ID_CREATE_CHILD_GROUP : recvCreateChildGroup(event) ; return true ; break ; default : return false ; } } } template void CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr) { StdString name = node.getElementName(); xml::THashAttributes attributes = node.getAttributes(); if (withAttr) { CGroupTemplate::SuperClass::parse(node); if (attributes.end() != attributes.find("src")) { StdIFStream ifs ( attributes["src"].c_str() , StdIFStream::in ); if ( (ifs.rdstate() & std::ifstream::failbit ) != 0 ) ERROR("void CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr)", < file" ); if (!ifs.good()) ERROR("CGroupTemplate::parse(xml::CXMLNode & node, bool withAttr)", << "[ filename = " << attributes["src"] << " ] Bad xml stream !"); xml::CXMLParser::ParseInclude(ifs, attributes["src"].c_str(), *this); } } // PARSING POUR GESTION DES ENFANTS V* group_ptr = (this->hasId()) ? V::get(this->getId()) : boost::polymorphic_downcast(this); if (!(node.goToChildElement())) { if (this->hasId()) { DEBUG(<< "L'objet de type \'" << V::GetName() << "\' nommé \'" << this->getId() << "\' ne contient pas d\'enfant !"); } } else { do { // Parcours pour traitement. StdString name = node.getElementName(); attributes.clear(); attributes = node.getAttributes(); if (name.compare(V::GetName()) == 0) { if (attributes.end() == attributes.find("id")) CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node); else CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node); continue; } if (name.compare(U::GetName()) == 0) { if (attributes.end() == attributes.find("id")) CGroupFactory::CreateChild(group_ptr->getShared())->parse(node); else CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node); continue; } DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId() << "\', un objet de type \'" << V::GetName() << "\' ne peut contenir qu'un objet de type \'" << V::GetName() << "\' ou de type \'" << U::GetName() << "\' (reçu : " << name << ") !"); } while (node.goToNextElement()); node.goToParentElement(); // Retour au parent } } template void CGroupTemplate::parseChild(xml::CXMLNode & node) { // PARSING POUR GESTION DES ENFANTS V* group_ptr = (this->hasId()) ? V::get(this->getId()) : boost::polymorphic_downcast(this); StdString name = node.getElementName(); xml::THashAttributes attributes = node.getAttributes(); if (name.compare(V::GetName()) == 0) { if (attributes.end() == attributes.find("id")) CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node); else CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node); return ; } else if (name.compare(U::GetName()) == 0) { if (attributes.end() == attributes.find("id")) CGroupFactory::CreateChild(group_ptr->getShared())->parse(node); else CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node); return ; } DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId() << "\', un objet de type \'" << V::GetName() << "\' ne peut contenir qu'un objet de type \'" << V::GetName() << "\' ou de type \'" << U::GetName() << "\' (reçu : " << name << ") !"); } } // namespace xios #endif // __XIOS_CGroupTemplate_impl__