source: XIOS/dev/branch_openmp/src/group_template_impl.hpp @ 1460

Last change on this file since 1460 was 1460, checked in by yushan, 3 years ago

branch_openmp merged with XIOS_DEV_CMIP6@1459

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
File size: 20.2 KB
Line 
1#ifndef __XIOS_CGroupTemplate_impl__
2#define __XIOS_CGroupTemplate_impl__
3
4#include "xios_spl.hpp"
5#include "event_server.hpp"
6#include "object_template.hpp"
7#include "group_template.hpp"
8#include "context.hpp"
9#include "event_client.hpp"
10#include "context_client.hpp"
11#include "message.hpp"
12#include "type.hpp"
13#include "type_util.hpp"
14
15
16namespace xios
17{
18
19   /// ////////////////////// Définitions ////////////////////// ///
20
21   template <class U, class V, class W>
22      CGroupTemplate<U, V, W>::CGroupTemplate(void)
23         : CObjectTemplate<V>() //, V()
24         , childMap(), childList()
25         , groupMap(), groupList()
26   { /* Ne rien faire de plus */ }
27
28   template <class U, class V, class W>
29      CGroupTemplate<U, V, W>::CGroupTemplate(const StdString & id)
30         : CObjectTemplate<V>(id) //, V()
31         , childMap(), childList()
32         , groupMap(), groupList()
33   { /* Ne rien faire de plus */ }
34
35   template <class U, class V, class W>
36      CGroupTemplate<U, V, W>::~CGroupTemplate(void)
37   { /* Ne rien faire de plus */ }
38   
39   ///--------------------------------------------------------------
40/*
41   template <class U, class V, class W>
42      void CGroupTemplate<U, V, W>::toBinary(StdOStream & os) const
43   {
44      SuperClass::toBinary(os);
45     
46      const StdSize grpnb = this->groupList.size();
47      const StdSize chdnb = this->childList.size();
48      ENodeType cenum = U::GetType();
49      ENodeType genum = V::GetType();
50     
51      os.write (reinterpret_cast<const char*>(&grpnb) , sizeof(StdSize));
52      os.write (reinterpret_cast<const char*>(&chdnb) , sizeof(StdSize));     
53     
54      typename std::vector<V*>::const_iterator 
55         itg = this->groupList.begin(), endg = this->groupList.end();
56      typename std::vector<U*>::const_iterator
57         itc = this->childList.begin(), endc = this->childList.end();
58           
59      for (; itg != endg; itg++)
60      {
61         V* group = *itg;
62         bool hid = group->hasId();
63         
64         os.write (reinterpret_cast<const char*>(&genum), sizeof(ENodeType));     
65         os.write (reinterpret_cast<const char*>(&hid), sizeof(bool));
66         
67         if (hid)
68         {
69            const StdString & id = group->getId();
70            const StdSize size   = id.size();
71               
72            os.write (reinterpret_cast<const char*>(&size), sizeof(StdSize));
73            os.write (id.data(), size * sizeof(char));         
74         }             
75         group->toBinary(os);
76      }
77           
78      for (; itc != endc; itc++)
79      {
80         U* child = *itc;
81         bool hid = child->hasId();
82         
83         os.write (reinterpret_cast<const char*>(&cenum), sizeof(ENodeType));
84         os.write (reinterpret_cast<const char*>(&hid), sizeof(bool));
85         
86         if (hid)
87         {
88            const StdString & id = child->getId();
89            const StdSize size   = id.size();
90               
91            os.write (reinterpret_cast<const char*>(&size), sizeof(StdSize));
92            os.write (id.data(), size * sizeof(char));         
93         }         
94         child->toBinary(os);
95      }
96     
97   }
98   
99   template <class U, class V, class W>
100      void CGroupTemplate<U, V, W>::fromBinary(StdIStream & is)
101   {
102      SuperClass::fromBinary(is);
103     
104      V* group_ptr = (this->hasId())
105         ? V::get(this->getId())
106         : V::get((V*)this);
107     
108      StdSize grpnb = 0;
109      StdSize chdnb = 0;
110      ENodeType renum = Unknown;
111     
112      is.read (reinterpret_cast<char*>(&grpnb), sizeof(StdSize));
113      is.read (reinterpret_cast<char*>(&chdnb), sizeof(StdSize));
114     
115      for (StdSize i = 0; i < grpnb; i++)
116      {
117         bool hid = false;
118         is.read (reinterpret_cast<char*>(&renum), sizeof(ENodeType));
119         is.read (reinterpret_cast<char*>(&hid), sizeof(bool));
120         
121         if (renum != V::GetType())
122            ERROR("CGroupTemplate<U, V, W>::fromBinary(StdIStream & is)",
123                  << "[ renum = " << renum << "] Bad type !");
124                       
125         if (hid)
126         {
127            StdSize size  = 0;
128            is.read (reinterpret_cast<char*>(&size), sizeof(StdSize));
129            StdString id(size, ' ');
130            is.read (const_cast<char *>(id.data()), size * sizeof(char));
131            CGroupFactory::CreateGroup(group_ptr->getShared(), id)->fromBinary(is);
132         }
133         else
134         {
135            CGroupFactory::CreateGroup(group_ptr->getShared())->fromBinary(is);
136         }
137      }
138     
139      for (StdSize j = 0; j < chdnb; j++)
140      {
141         bool hid = false;
142         is.read (reinterpret_cast<char*>(&renum), sizeof(ENodeType));
143         is.read (reinterpret_cast<char*>(&hid), sizeof(bool));
144         
145         if (renum != U::GetType())
146            ERROR("CGroupTemplate<U, V, W>::fromBinary(StdIStream & is)",
147                  << "[ renum = " << renum << "] Bad type !");
148                 
149         if (hid)
150         {
151            StdSize size  = 0;
152            is.read (reinterpret_cast<char*>(&size), sizeof(StdSize));
153            StdString id(size, ' ');
154            is.read (const_cast<char *>(id.data()), size * sizeof(char));
155            CGroupFactory::CreateChild(group_ptr->getShared(), id)->fromBinary(is);           
156         }
157         else
158         {
159            CGroupFactory::CreateChild(group_ptr->getShared())->fromBinary(is);
160         }   
161      }
162   }
163*/
164   //--------------------------------------------------------------
165
166   template <class U, class V, class W>
167      StdString CGroupTemplate<U, V, W>::toString(void) const
168   {
169      StdOStringStream oss;
170      StdString name = (this->getId().compare(V::GetDefName()) != 0)
171                     ? V::GetName() : V::GetDefName();
172
173      oss << "<" << name << " ";
174      if (this->hasId() && (this->getId().compare(V::GetDefName()) != 0))
175         oss << " id=\"" << this->getId() << "\" ";
176         
177      if (this->hasChild())
178      {
179         oss << SuperClassAttribute::toString() << ">" << std::endl;
180         
181         typename std::vector<V*>::const_iterator
182            itg = this->groupList.begin(), endg = this->groupList.end();
183         typename std::vector<U*>::const_iterator
184            itc = this->childList.begin(), endc = this->childList.end();
185           
186         for (; itg != endg; itg++)
187         { 
188            V* group = *itg;
189            oss << *group << std::endl;
190         }
191           
192         for (; itc != endc; itc++)
193         { 
194            U* child = *itc;
195            oss << *child << std::endl;
196         }
197           
198         oss << "</" << name << " >";
199      }
200      else
201      {
202         oss << SuperClassAttribute::toString() << "/>";
203      }
204      return (oss.str());
205   }
206
207   template <class U, class V, class W>
208      void CGroupTemplate<U, V, W>::fromString(const StdString & str)
209   { 
210      ERROR("CGroupTemplate<U, V, W>::toString(void)",
211            << "[ str = " << str << "] Not implemented yet !");
212   }
213
214   //---------------------------------------------------------------
215
216   template <class U, class V, class W>
217      StdString CGroupTemplate<U, V, W>::GetName(void)
218   { 
219      return (U::GetName().append("_group")); 
220   }
221
222   template <class U, class V, class W>
223      StdString CGroupTemplate<U, V, W>::GetDefName(void)
224   { 
225      return (U::GetName().append("_definition")); 
226   }
227   
228   //---------------------------------------------------------------   
229
230   template <class U, class V, class W>
231      const std::vector<U*>&
232         CGroupTemplate<U, V, W>::getChildList(void) const
233   { 
234      return (this->childList); 
235   }
236
237   //---------------------------------------------------------------
238
239   template <class U, class V, class W>
240      const xios_map<StdString, V*>&
241         CGroupTemplate<U, V, W>::getGroupMap(void) const
242   { 
243      return (this->groupMap);
244   }
245
246   //---------------------------------------------------------------
247
248   template <class U, class V, class W>
249      bool CGroupTemplate<U, V, W>::hasChild(void) const
250   { 
251      return ((groupList.size() + childList.size()) > 0); 
252   }
253
254   //---------------------------------------------------------------
255
256   template <class U, class V, class W>
257      void CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node)
258   { 
259      this->parse(node, true); 
260   }
261   
262   //---------------------------------------------------------------
263   
264   template <class U, class V, class W>
265      void CGroupTemplate<U, V, W>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
266   {
267      if (parent != NULL)
268         SuperClassAttribute::setAttributes(parent, apply);
269         
270      typename std::vector<U*>::const_iterator
271         itc = this->childList.begin(), endc = this->childList.end();
272      typename std::vector<V*>::const_iterator
273         itg = this->groupList.begin(), endg = this->groupList.end();
274             
275      for (; itc != endc; itc++)
276      { 
277         U* child = *itc;
278         child->solveDescInheritance(apply,this);
279      }
280           
281      for (; itg != endg; itg++)
282      { 
283         V* group = *itg;
284         if (apply) group->solveRefInheritance();
285         group->solveDescInheritance(apply,this);
286      }
287   }
288
289   //---------------------------------------------------------------
290
291   template <class U, class V, class W>
292      void CGroupTemplate<U, V, W>::getAllChildren(std::vector<U*>& allc) const
293   {
294      allc.insert (allc.end(), childList.begin(), childList.end());
295      typename std::vector<V*>::const_iterator
296         itg = this->groupList.begin(), endg = this->groupList.end();
297         
298      for (; itg != endg; itg++)
299      { 
300         V* group = *itg;
301         group->getAllChildren(allc);
302      }
303   }
304
305   //---------------------------------------------------------------
306
307   template <class U, class V, class W>
308      std::vector<U*> CGroupTemplate<U, V, W>::getAllChildren(void) const
309   { 
310      std::vector<U*> allc;
311      this->getAllChildren(allc);
312      return (allc);
313   }
314
315   //---------------------------------------------------------------
316
317   template <class U, class V, class W>
318      void CGroupTemplate<U, V, W>::solveRefInheritance(void)
319   { /* Ne rien faire de plus */ }
320   
321//   template <class U, class V, class W>
322//   bool CGroupTemplate<U, V, W>::has(const string& id)
323//   {
324//       return CObjectFactory::HasObject<V>(id) ;
325//   }
326
327//   template <class U, class V, class W>
328//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::get(const string& id)
329//   {
330//       return CObjectFactory::GetObject<V>(id) ;
331//   }
332
333//   template <class U, class V, class W>
334//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::get()
335//   {
336//       return CObjectFactory::GetObject<V>(this) ;
337//   }
338   
339//   template <class U, class V, class W>
340//   boost::shared_ptr<V> CGroupTemplate<U, V, W>::create(const string& id)
341//   {
342//       return CObjectFactory::CreateObject<V>(id) ;
343//   }
344   ///--------------------------------------------------------------
345
346 
347   template <class U, class V, class W>
348   U* CGroupTemplate<U, V, W>::createChild(const string& id) 
349  {
350    return CGroupFactory::CreateChild<V>(this->getShared(), id).get() ;
351  }
352
353   template <class U, class V, class W>
354   void CGroupTemplate<U, V, W>::addChild(U* child) 
355  {
356    return CGroupFactory::AddChild<V>(this->getShared(),child->getShared()) ;
357  }
358 
359   template <class U, class V, class W>
360   V* CGroupTemplate<U, V, W>::createChildGroup(const string& id) 
361  {
362    return CGroupFactory::CreateGroup<V>(this->getShared(), id).get() ;
363  }
364
365   template <class U, class V, class W>
366   void CGroupTemplate<U, V, W>::addChildGroup(V* childGroup) 
367  {
368    return CGroupFactory::AddGroup<V>(this->getShared(), childGroup->getShared()) ;
369  }
370
371
372   template <class U, class V, class W>
373   void CGroupTemplate<U, V, W>::sendCreateChild(const string& id)
374   {
375    CContext* context=CContext::getCurrent() ; 
376
377    if (context->hasClient)
378    // if (!context->hasServer )
379    {
380      // Use correct context client to send message
381//      CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
382      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
383      for (int i = 0; i < nbSrvPools; ++i)
384      {
385         CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
386
387         CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;
388         if (contextClientTmp->isServerLeader())
389         {
390           CMessage msg ;
391           msg<<this->getId() ;
392           msg<<id ;
393           const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
394           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
395             event.push(*itRank,1,msg) ;
396           contextClientTmp->sendEvent(event) ;
397         }
398         else contextClientTmp->sendEvent(event) ;
399      }
400    }
401     
402   }
403
404   template <class U, class V, class W>
405   void CGroupTemplate<U, V, W>::sendCreateChild(const string& id, CContextClient* client)
406   {
407
408    CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;
409    if (client->isServerLeader())
410    {
411      CMessage msg ;
412      msg<<this->getId() ;
413      msg<<id ;
414      const std::list<int>& ranks = client->getRanksServerLeader();
415      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
416       event.push(*itRank,1,msg) ;
417      client->sendEvent(event) ;
418    }
419    else client->sendEvent(event) ;
420   }
421
422
423   template <class U, class V, class W>
424   void CGroupTemplate<U, V, W>::sendCreateChildGroup(const string& id)
425   {
426    CContext* context=CContext::getCurrent() ;
427    if (context->hasClient)
428    {
429      // Use correct context client to send message
430      // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
431      int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
432      for (int i = 0; i < nbSrvPools; ++i)
433      {
434        CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
435        CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD_GROUP) ;
436        if (contextClientTmp->isServerLeader())
437        {
438          CMessage msg ;
439          msg<<this->getId() ;
440          msg<<id ;
441          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
442          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
443            event.push(*itRank,1,msg) ;
444          contextClientTmp->sendEvent(event) ;
445        }
446        else contextClientTmp->sendEvent(event) ;
447      }
448    }
449   }
450   
451   template <class U, class V, class W>
452   void CGroupTemplate<U, V, W>::recvCreateChild(CEventServer& event)
453   {
454      CBufferIn* buffer=event.subEvents.begin()->buffer;
455      string id;
456      *buffer>>id ;
457      V::get(id)->recvCreateChild(*buffer) ;
458   }
459   
460   
461   template <class U, class V, class W>
462   void CGroupTemplate<U, V, W>::recvCreateChild(CBufferIn& buffer)
463   {
464      string id ;
465      buffer>>id ;
466      createChild(id) ;
467   }
468
469   template <class U, class V, class W>
470   void CGroupTemplate<U, V, W>::recvCreateChildGroup(CEventServer& event)
471   {
472     
473      CBufferIn* buffer=event.subEvents.begin()->buffer;
474      string id;
475      *buffer>>id ;
476      V::get(id)->recvCreateChildGroup(*buffer) ;
477   }
478   
479   
480   template <class U, class V, class W>
481   void CGroupTemplate<U, V, W>::recvCreateChildGroup(CBufferIn& buffer)
482   {
483      string id ;
484      buffer>>id ;
485      createChildGroup(id) ;
486   }
487   
488
489   template <class U, class V, class W>
490   bool CGroupTemplate<U, V, W>::dispatchEvent(CEventServer& event)
491   {
492      if (CObjectTemplate<V>::dispatchEvent(event)) return true ;
493      else
494      {
495        switch(event.type)
496        {
497           case EVENT_ID_CREATE_CHILD :
498             recvCreateChild(event) ;
499             return true ;
500             break ;
501         
502           case EVENT_ID_CREATE_CHILD_GROUP :
503             recvCreateChildGroup(event) ;
504             return true ;
505             break ;       
506         
507           default :
508           return false ;
509        }
510      }
511   }
512
513   template <class U, class V, class W>
514      void CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node, bool withAttr)
515   {
516
517      StdString name = node.getElementName();
518      xml::THashAttributes attributes = node.getAttributes();
519      if (withAttr)
520      {
521         CGroupTemplate<U, V, W>::SuperClass::parse(node);
522         if (attributes.end() != attributes.find("src"))
523         {
524            StdIFStream ifs ( attributes["src"].c_str() , StdIFStream::in );
525            if ( (ifs.rdstate() & std::ifstream::failbit ) != 0 )
526               ERROR("void CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node, bool withAttr)",
527                     <<endl<< "Can not open <"<<attributes["src"].c_str()<<"> file" );
528           
529            if (!ifs.good())
530               ERROR("CGroupTemplate<U, V, W>::parse(xml::CXMLNode & node, bool withAttr)",
531                     << "[ filename = " << attributes["src"] << " ] Bad xml stream !");
532            xml::CXMLParser::ParseInclude(ifs, attributes["src"].c_str(), *this);
533         }
534      }
535
536      // PARSING POUR GESTION DES ENFANTS
537           V* group_ptr = (this->hasId()) 
538         ? V::get(this->getId())
539         : boost::polymorphic_downcast<V*>(this);
540
541      if (!(node.goToChildElement()))
542      {
543         if (this->hasId())
544         {
545            DEBUG(<< "L'objet de type \'" << V::GetName()
546                  << "\' nommé \'" << this->getId()
547                  << "\' ne contient pas d\'enfant !");
548         }
549      }
550      else
551      {
552         do { // Parcours pour traitement.
553
554            StdString name = node.getElementName();
555            attributes.clear();
556            attributes = node.getAttributes();
557
558            if (name.compare(V::GetName()) == 0)
559            {
560               if (attributes.end() == attributes.find("id"))
561                  CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node);
562               else
563                  CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node);
564               continue;
565            }
566
567            if (name.compare(U::GetName()) == 0)
568            {
569               if (attributes.end() == attributes.find("id"))
570                  CGroupFactory::CreateChild(group_ptr->getShared())->parse(node);
571               else
572                  CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node);
573               continue;
574            }
575
576            DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId()
577                  << "\', un objet de type \'" << V::GetName()
578                  << "\' ne peut contenir qu'un objet de type \'" << V::GetName()
579                  << "\' ou de type \'" << U::GetName()
580                  << "\' (reçu : " << name << ") !");
581
582         } while (node.goToNextElement());
583         node.goToParentElement(); // Retour au parent
584      }
585   }
586   
587   template <class U, class V, class W>
588   void CGroupTemplate<U, V, W>::parseChild(xml::CXMLNode & node)
589   {
590
591
592      // PARSING POUR GESTION DES ENFANTS
593           V* group_ptr = (this->hasId()) 
594         ? V::get(this->getId())
595         : boost::polymorphic_downcast<V*>(this);
596
597          StdString name = node.getElementName();
598          xml::THashAttributes attributes = node.getAttributes();
599
600          if (name.compare(V::GetName()) == 0)
601          {
602             if (attributes.end() == attributes.find("id"))
603                CGroupFactory::CreateGroup(group_ptr->getShared())->parse(node);
604             else
605                CGroupFactory::CreateGroup(group_ptr->getShared(), attributes["id"])->parse(node);
606             return ;
607          }
608          else if (name.compare(U::GetName()) == 0)
609          {
610             if (attributes.end() == attributes.find("id"))
611                CGroupFactory::CreateChild(group_ptr->getShared())->parse(node);
612             else
613                CGroupFactory::CreateChild(group_ptr->getShared(), attributes["id"])->parse(node);
614             return ;
615          }
616
617          DEBUG(<< "Dans le contexte \'" << CContext::getCurrent()->getId()
618                << "\', un objet de type \'" << V::GetName()
619                << "\' ne peut contenir qu'un objet de type \'" << V::GetName()
620                << "\' ou de type \'" << U::GetName()
621                << "\' (reçu : " << name << ") !");
622
623   }
624} // namespace xios
625
626
627#endif // __XIOS_CGroupTemplate_impl__
Note: See TracBrowser for help on using the repository browser.