source: XIOS/dev/dev_olga/src/group_template_impl.hpp @ 1148

Last change on this file since 1148 was 1030, checked in by oabramkina, 7 years ago

dev: intermediate commit.

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