#ifndef __XIOS_CObjectTemplate_impl__ #define __XIOS_CObjectTemplate_impl__ #include "xios_spl.hpp" #include "context_client.hpp" #include "object_factory.hpp" #include "context.hpp" #include "buffer_in.hpp" #include "attribute.hpp" #include "event_client.hpp" #include "object_template.hpp" #include "context_client.hpp" #include "indent.hpp" #include "type_util.hpp" #include "message.hpp" #include "type.hpp" #include "type_util.hpp" #include "group_template.hpp" namespace xios { /// ////////////////////// Définitions ////////////////////// /// template xios_map > > *CObjectTemplate::AllMapObj_ptr = 0; template xios_map > > *CObjectTemplate::AllVectObj_ptr = 0; template xios_map *CObjectTemplate::GenId_ptr = 0; template CObjectTemplate::CObjectTemplate(void) : CAttributeMap() , CObject() { /* Ne rien faire de plus */ } template CObjectTemplate::CObjectTemplate(const StdString & id) : CAttributeMap() , CObject(id, CObjectFactory::IsGenUId(id)) { /* Ne rien faire de plus */ } template CObjectTemplate::CObjectTemplate (const CObjectTemplate & object, bool withAttrList, bool withId) : CAttributeMap() , CObject() { if (object.hasId() && withId) this->setId(object.getId(), object.hasAutoGeneratedId()); ERROR("CObjectTemplate construtor 3", << "Not completly implemented yet !"); } template CObjectTemplate::~CObjectTemplate(void) { /* Ne rien faire de plus */ } ///-------------------------------------------------------------- template std::vector > & CObjectTemplate::GetAllVectobject(const StdString & contextId) { return (CObjectTemplate::AllVectObj_ptr->at(contextId)); } //--------------------------------------------------------------- template StdString CObjectTemplate::toString(void) const { StdOStringStream oss; oss << "<" << T::GetName(); if (this->hasId()) oss << " id=\"" << this->getId() << "\""; oss << " " << SuperClassMap::toString() << "/>"; return (oss.str()); } template void CObjectTemplate::fromString(const StdString & str) { ERROR("CObjectTemplate::fromString(str)", << "[ str = " << str << "] Not implemented yet !"); } //--------------------------------------------------------------- /* template void CObjectTemplate::toBinary(StdOStream & os) const { SuperClassMap::toBinary(os); } template void CObjectTemplate::fromBinary(StdIStream & is) { SuperClassMap::fromBinary(is); } */ //--------------------------------------------------------------- template void CObjectTemplate::parse(xml::CXMLNode & node) { xml::THashAttributes attributes = node.getAttributes(); CAttributeMap::setAttributes(attributes); } //--------------------------------------------------------------- template ENodeType CObjectTemplate::getType(void) const { return (T::GetType()); } template string CObjectTemplate::getName(void) const { return (T::GetName()); } //--------------------------------------------------------------- template bool CObjectTemplate::hasChild(void) const { return (false); } /*! Compare two object of same type */ template bool CObjectTemplate::isEqual(const string& id, const vector& excludedAttrs) { T* obj = CObjectTemplate::get(id); return this->isEqual(obj, excludedAttrs); } template bool CObjectTemplate::isEqual(T* obj, const vector& excludedAttrs) { CAttributeMap& attrMapThis = *this; CAttributeMap& attrMapObj = *obj; return (attrMapThis.isEqual(attrMapObj, excludedAttrs)); } //--------------------------------------------------------------- template void CObjectTemplate::solveDescInheritance(bool apply, const CAttributeMap * const parent) { if (parent != NULL) SuperClassMap::setAttributes(parent, apply); } //--------------------------------------------------------------- template void CObjectTemplate::ClearAllAttributes(void) { vector avect = CObjectTemplate::getAll(); typename vector::iterator it = avect.begin(), end = avect.end(); for (;it != end; it++) { CAttributeMap & amap = **it; amap.clearAllAttributes(); } } template std::map CObjectTemplate::getMinimumBufferSizeForAttributes(CContextClient* client) { std::map minimumSizes; if (client->isServerLeader()) { size_t minimumSize = 0; CAttributeMap& attrMap = *this; CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end(); for (; it != itE; ++it) { if (!it->second->isEmpty()) { size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size(); if (size > minimumSize) minimumSize = size; } } if (minimumSize) { // Account for extra header info minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t); const std::list& ranks = client->getRanksServerLeader(); for (std::list::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) minimumSizes.insert(std::make_pair(*itRank, minimumSize)); } } return minimumSizes; } template void CObjectTemplate::sendAllAttributesToServer() { CAttributeMap& attrMap = *this; CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end(); for (; it != itE; ++it) { if (it->second->doSend() && !(it->second)->isEmpty()) sendAttributToServer(*(it->second)); } } template void CObjectTemplate::sendAllAttributesToServer(CContextClient* client) { CAttributeMap& attrMap = *this; CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end(); for (; it != itE; ++it) { if (it->second->doSend() && !(it->second)->isEmpty()) sendAttributToServer(*(it->second), client); } } template void CObjectTemplate::sendAttributToServer(const string& id) { CAttributeMap & attrMap = *this; CAttribute* attr=attrMap[id]; sendAttributToServer(*attr); } template void CObjectTemplate::sendAttributToServer(const string& id, CContextClient* client) { CAttributeMap & attrMap = *this; CAttribute* attr=attrMap[id]; sendAttributToServer(*attr, client); } template void CObjectTemplate::sendAttributToServer(CAttribute& attr) { // Use correct context client to send message CContext* context=CContext::getCurrent(); if (context->hasClient) { // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; for (int i = 0; i < nbSrvPools; ++i) { CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client; CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE); if (contextClientTmp->isServerLeader()) { CMessage msg; msg<getIdServer(); msg << attr.getName(); msg << attr; const std::list& 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 CObjectTemplate::sendAttributToServer(CAttribute& attr, CContextClient* client) { CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE); if (client->isServerLeader()) { CMessage msg; msg<getIdServer(); msg << attr.getName(); msg << attr; const std::list& 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); } /*! This generic funtion only provides instance for sending, for receving, each child class must define itself. \param [in] id Id of added item \param [in] itemType type of added item */ template void CObjectTemplate::sendAddItem(const StdString& id, int itemType) { CContext* context = CContext::getCurrent(); typedef typename T::EEventId ItemType; 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() : 0) : 1; for (int i = 0; i < nbSrvPools; ++i) { CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client; CEventClient event(this->getType(),ItemType(itemType)); if (contextClientTmp->isServerLeader()) { CMessage msg; msg << this->getId(); msg << id; const std::list& 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 CObjectTemplate::sendAddItem(const StdString& id, int itemType, CContextClient* client) { typedef typename T::EEventId ItemType; CEventClient event(this->getType(),ItemType(itemType)); if (client->isServerLeader()) { CMessage msg; msg << this->getId(); msg << id; const std::list& 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 CObjectTemplate::recvAttributFromClient(CEventServer& event) { CBufferIn* buffer=event.subEvents.begin()->buffer; string id,attrId; *buffer>>id; CAttributeMap & attrMap = *get(id); *buffer>>attrId; CAttribute* attr=attrMap[attrId]; info(50) << "attribut recu " << attrId << " "; if (attr->isEmpty()) info(50) << "--> empty" << endl; else info(50) /*getValue()*/ << endl; *buffer>>*attr; info(50) << "attribut recu " << attrId << " "; if (attr->isEmpty()) info(50) << "--> empty" << endl; else info(50) /*attr->getValue()*/ << endl; } template bool CObjectTemplate::dispatchEvent(CEventServer& event) { switch(event.type) { case EVENT_ID_SEND_ATTRIBUTE : recvAttributFromClient(event); return true; break; default : return false; // ERROR("void CObjectTemplate::recvEvent(CEventServer& event)", << "Unknown Event"); } } template bool CObjectTemplate::has(const string & id) { return CObjectFactory::HasObject(id); } template bool CObjectTemplate::has(const string& contextId, const string & id) { return CObjectFactory::HasObject(contextId,id); } template T* CObjectTemplate::get(const string & id) { return CObjectFactory::GetObject(id).get(); } template T* CObjectTemplate::get(const T* ptr) { return CObjectFactory::GetObject(ptr).get(); } template std::shared_ptr CObjectTemplate::getShared(const T* ptr) { return CObjectFactory::GetObject(ptr); } template std::shared_ptr CObjectTemplate::getShared(void) { return CObjectFactory::GetObject((T*)this); } template const vector CObjectTemplate::getAll() { int mycheck = CObjectFactory::CheckObjectVector(); if(mycheck==0) { vector vect; return vect; } const vector< std::shared_ptr >& shared_vect= CObjectFactory::GetObjectVector(CObjectFactory::GetCurrentContextId()); vector vect; typename vector >::const_iterator it; for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get()); return vect; } template const vector CObjectTemplate::getAll(const string & id) { const vector< std::shared_ptr >& shared_vect= CObjectFactory::GetObjectVector(id); vector vect; typename vector >::const_iterator it; for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get()); return vect; } template T* CObjectTemplate::get(const string& contextId, const string & id) { return CObjectFactory::GetObject(contextId,id).get(); } template T* CObjectTemplate::create(const string & id) { return CObjectFactory::CreateObject(id).get(); } ///-------------------------------------------------------------- template T* CObjectTemplate::get(void) { return CObjectFactory::GetObject((T*)this).get(); } template void CObjectTemplate::generateCInterface(ostream& oss) { string className=getName(); int found=className.rfind("_group"); if (found!=string::npos) className.replace(found,1,0,'x'); oss << "/* ************************************************************************** *" << iendl; oss << " * Interface auto generated - do not modify *" << iendl; oss << " * ************************************************************************** */" << iendl; oss << iendl; oss << "#include " << iendl; oss << "#include " << iendl; oss << "#include \"xios.hpp\"" << iendl; oss << "#include \"attribute_template.hpp\"" << iendl; oss << "#include \"object_template.hpp\"" << iendl; oss << "#include \"group_template.hpp\"" << iendl; oss << "#include \"icutil.hpp\"" << iendl; oss << "#include \"icdate.hpp\"" << iendl; oss << "#include \"timer.hpp\"" << iendl; oss << "#include \"node_type.hpp\"" << iendl; oss << iendl; oss << "extern \"C\"" << iendl; oss << "{" << iendl++; oss << "typedef xios::" << getStrType() << "* " << className << "_Ptr;"; SuperClassMap::generateCInterface(oss,className); oss << "}" << iendl--; } template void CObjectTemplate::generateFortran2003Interface(ostream& oss) { string className=getName(); int found=className.rfind("_group"); if (found!=string::npos) className.replace(found,1,0,'x'); oss << "! * ************************************************************************** *" << iendl; oss << "! * Interface auto generated - do not modify *" << iendl; oss << "! * ************************************************************************** *" << iendl; oss << "#include \"../fortran/xios_fortran_prefix.hpp\"" << iendl; oss << iendl; oss << "MODULE " << className << "_interface_attr" << iendl++; oss << "USE, INTRINSIC :: ISO_C_BINDING" << std::endl; oss << iendl; oss << "INTERFACE" << iendl++; oss << "! Do not call directly / interface FORTRAN 2003 <-> C99"; SuperClassMap::generateFortran2003Interface(oss,className); oss << iendl--; oss << "END INTERFACE" << iendl--; oss << iendl; oss << "END MODULE " << className << "_interface_attr" << iendl; } template void CObjectTemplate::generateFortranInterface(ostream& oss) { string className=getName(); int found=className.rfind("_group"); if (found!=string::npos) className.erase(found,1); string superClassName=getName(); found=superClassName.find("_group"); if (found!=string::npos) superClassName.erase(found,6); oss << "! * ************************************************************************** *" << iendl; oss << "! * Interface auto generated - do not modify *" << iendl; oss << "! * ************************************************************************** *" << iendl; oss << "#include \"xios_fortran_prefix.hpp\"" << iendl; oss << iendl; oss << "MODULE i" << className << "_attr" << iendl++; oss << "USE, INTRINSIC :: ISO_C_BINDING" << iendl; oss << "USE i" << superClassName << iendl; oss << "USE " << className << "_interface_attr" << iendl--; // oss << "TYPE txios(" << className << ")" << iendl; // oss << " INTEGER(kind = C_INTPTR_T) :: daddr" << iendl; // oss << "END TYPE txios(" << className << ")" << iendl; oss << iendl; oss << "CONTAINS" << iendl; oss << iendl++; SuperClassMap::generateFortranInterface_id(oss,className); oss << iendl; SuperClassMap::generateFortranInterface_hdl(oss,className); oss << iendl; SuperClassMap::generateFortranInterface_hdl_(oss,className); oss << iendl; SuperClassMap::generateFortranInterfaceGet_id(oss,className); oss << iendl; SuperClassMap::generateFortranInterfaceGet_hdl(oss,className); oss << iendl; SuperClassMap::generateFortranInterfaceGet_hdl_(oss,className); oss << iendl; SuperClassMap::generateFortranInterfaceIsDefined_id(oss,className); oss << iendl; SuperClassMap::generateFortranInterfaceIsDefined_hdl(oss,className); oss << iendl; SuperClassMap::generateFortranInterfaceIsDefined_hdl_(oss,className); oss << iendl--; oss << "END MODULE i" << className << "_attr" << iendl; } } // namespace xios #endif // __XIOS_CObjectTemplate_impl__