source: XIOS/dev/dev_olga/src/object_template_impl.hpp @ 1023

Last change on this file since 1023 was 1021, checked in by oabramkina, 7 years ago

Intermeadiate version for merging with new server functionalities.

  • 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: 19.7 KB
Line 
1#ifndef __XIOS_CObjectTemplate_impl__
2#define __XIOS_CObjectTemplate_impl__
3
4#include "xios_spl.hpp"
5#include "context_client.hpp"
6#include "object_factory.hpp"
7#include "context.hpp"
8#include "buffer_in.hpp"
9#include "attribute.hpp"
10#include "event_client.hpp"
11#include "object_template.hpp"
12#include "context_client.hpp"
13#include "indent.hpp"
14#include "type_util.hpp"
15#include "message.hpp"
16#include "type.hpp"
17#include "type_util.hpp"
18#include "group_template.hpp"
19
20namespace xios
21{
22   /// ////////////////////// Définitions ////////////////////// ///
23   template <class T>
24      xios_map<StdString,
25      xios_map<StdString,
26      boost::shared_ptr<T> > > CObjectTemplate<T>::AllMapObj;
27
28   template <class T>
29      xios_map<StdString,
30      std::vector<boost::shared_ptr<T> > > CObjectTemplate<T>::AllVectObj;
31
32   template <class T>
33      xios_map<StdString,long int> CObjectTemplate<T>::GenId;
34
35   template <class T>
36      CObjectTemplate<T>::CObjectTemplate(void)
37         : CAttributeMap()
38         , CObject()
39   { /* Ne rien faire de plus */ }
40
41   template <class T>
42      CObjectTemplate<T>::CObjectTemplate(const StdString & id)
43         : CAttributeMap()
44         , CObject(id, CObjectFactory::IsGenUId<T>(id))
45   { /* Ne rien faire de plus */ }
46
47   template <class T>
48      CObjectTemplate<T>::CObjectTemplate
49         (const CObjectTemplate<T> & object, bool withAttrList, bool withId)
50         : CAttributeMap()
51         , CObject()
52   {
53      if (object.hasId() && withId)
54         this->setId(object.getId(), object.hasAutoGeneratedId());
55      ERROR("CObjectTemplate<T> construtor 3", << "Not completly implemented yet !");
56   }
57
58   template <class T>
59      CObjectTemplate<T>::~CObjectTemplate(void)
60   { /* Ne rien faire de plus */ }
61
62   ///--------------------------------------------------------------
63
64   template <class T>
65      std::vector<boost::shared_ptr<T> > &
66         CObjectTemplate<T>::GetAllVectobject(const StdString & contextId)
67   {
68      return (CObjectTemplate<T>::AllVectObj[contextId]);
69   }
70
71   //---------------------------------------------------------------
72
73   template <class T>
74      StdString CObjectTemplate<T>::toString(void) const
75   {
76      StdOStringStream oss;
77      oss << "<" << T::GetName();
78      if (this->hasId())
79         oss << " id=\"" << this->getId() << "\"";
80      oss << " " << SuperClassMap::toString() << "/>";
81      return (oss.str());
82   }
83
84   template <class T>
85      void CObjectTemplate<T>::fromString(const StdString & str)
86   {
87      ERROR("CObjectTemplate<T>::fromString(str)",
88            << "[ str = " << str << "] Not implemented yet !");
89   }
90
91   //---------------------------------------------------------------
92
93/*
94   template <class T>
95      void CObjectTemplate<T>::toBinary(StdOStream & os) const
96   {
97      SuperClassMap::toBinary(os);
98   }
99
100   template <class T>
101      void CObjectTemplate<T>::fromBinary(StdIStream & is)
102   {
103      SuperClassMap::fromBinary(is);
104   }
105*/
106
107   //---------------------------------------------------------------
108
109   template <class T>
110      void CObjectTemplate<T>::parse(xml::CXMLNode & node)
111   {
112      xml::THashAttributes attributes = node.getAttributes();
113      CAttributeMap::setAttributes(attributes);
114   }
115
116   //---------------------------------------------------------------
117
118   template <class T>
119      ENodeType CObjectTemplate<T>::getType(void) const
120   {
121      return (T::GetType());
122   }
123
124   template <class T>
125   string CObjectTemplate<T>::getName(void) const
126   {
127      return (T::GetName());
128   }
129
130   //---------------------------------------------------------------
131
132   template <class T>
133      bool CObjectTemplate<T>::hasChild(void) const
134   {
135      return (false);
136   }
137
138   //---------------------------------------------------------------
139
140   template <class T>
141      void CObjectTemplate<T>::solveDescInheritance(bool apply, const CAttributeMap * const parent)
142   {
143      if (parent != NULL)
144         SuperClassMap::setAttributes(parent, apply);
145   }
146
147   //---------------------------------------------------------------
148
149   template <class T>
150      void CObjectTemplate<T>::ClearAllAttributes(void)
151   {
152      vector<T*> avect = CObjectTemplate<T>::getAll();
153      typename vector<T*>::iterator
154            it = avect.begin(), end = avect.end();
155
156      for (;it != end; it++)
157      {
158         CAttributeMap & amap = **it;
159         amap.clearAllAttributes();
160      }
161   }
162
163   template<typename T>
164   std::map<int, size_t> CObjectTemplate<T>::getMinimumBufferSizeForAttributes()
165   {
166     // Use correct context client to send message
167     CContext* context = CContext::getCurrent();
168     int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
169     for (int i = 0; i < nbSrvPools; ++i)
170     {
171       CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
172
173       std::map<int, size_t> minimumSizes;
174
175       if (contextClientTmp->isServerLeader())
176       {
177         size_t minimumSize = 0;
178         CAttributeMap& attrMap = *this;
179         CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
180         for (; it != itE; ++it)
181         {
182           if (!it->second->isEmpty())
183           {
184             size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
185             if (size > minimumSize)
186               minimumSize = size;
187           }
188         }
189
190         if (minimumSize)
191         {
192           // Account for extra header info
193           minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
194
195           const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
196           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
197             minimumSizes.insert(std::make_pair(*itRank, minimumSize));
198         }
199       }
200
201     // if (client->isServerLeader())
202     // {
203     //   size_t minimumSize = 0;
204     //   CAttributeMap& attrMap = *this;
205     //   CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
206     //   for (; it != itE; ++it)
207     //   {
208     //     if (!it->second->isEmpty())
209     //     {
210     //       size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
211     //       if (size > minimumSize)
212     //         minimumSize = size;
213     //     }
214     //   }
215
216     //   if (minimumSize)
217     //   {
218     //     // Account for extra header info
219     //     minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
220
221     //     const std::list<int>& ranks = client->getRanksServerLeader();
222     //     for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
223     //       minimumSizes.insert(std::make_pair(*itRank, minimumSize));
224     //   }
225     // }
226
227       return minimumSizes;
228     }
229   }
230
231   template<typename T>
232   void CObjectTemplate<T>::sendAllAttributesToServer()
233   {
234     CAttributeMap& attrMap = *this;
235     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
236     for (; it != itE; ++it)
237     {
238       if (!(it->second)->isEmpty()) sendAttributToServer(*(it->second));
239     }
240   }
241
242   template<typename T>
243   void CObjectTemplate<T>::sendAllAttributesToServer(CContextClient* client)
244   {
245     CAttributeMap& attrMap = *this;
246     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
247     for (; it != itE; ++it)
248     {
249       if (!(it->second)->isEmpty()) sendAttributToServer(*(it->second), client);
250     }
251   }
252
253   template <class T>
254   void CObjectTemplate<T>::sendAttributToServer(const string& id)
255   {
256      CAttributeMap & attrMap = *this;
257      CAttribute* attr=attrMap[id];
258      sendAttributToServer(*attr);
259   }
260
261   template <class T>
262   void CObjectTemplate<T>::sendAttributToServer(const string& id, CContextClient* client)
263   {
264      CAttributeMap & attrMap = *this;
265      CAttribute* attr=attrMap[id];
266      sendAttributToServer(*attr, client);
267   }
268
269  template <class T>
270  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr)
271  {
272     // Use correct context client to send message
273    CContext* context=CContext::getCurrent();
274    if (context->hasClient)
275    {
276      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
277      for (int i = 0; i < nbSrvPools; ++i)
278      {
279        CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
280        CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
281        if (contextClientTmp->isServerLeader())
282        {
283          CMessage msg;
284          msg<<this->getIdServer();
285          msg << attr.getName();
286          msg << attr;
287          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
288          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
289            event.push(*itRank,1,msg);
290          contextClientTmp->sendEvent(event);
291        }
292        else contextClientTmp->sendEvent(event);
293      }
294    }
295//     // if (!context->hasServer)
296//     if (context->hasClient)
297//     {
298//        CContextClient* client=context->client;
299
300//        CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
301//        if (client->isServerLeader())
302//        {
303//          CMessage msg;
304// //       msg << this->getId();
305//          msg << this->getIdServer();
306//          msg << attr.getName();
307//          msg << attr;
308//          const std::list<int>& ranks = client->getRanksServerLeader();
309//          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
310//            event.push(*itRank,1,msg);
311//          client->sendEvent(event);
312//        }
313//        else client->sendEvent(event);
314//     }
315
316  }
317
318  template <class T>
319  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr, CContextClient* client)
320  {
321    CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
322    if (client->isServerLeader())
323    {
324      CMessage msg;
325      msg<<this->getIdServer();
326      msg << attr.getName();
327      msg << attr;
328      const std::list<int>& ranks = client->getRanksServerLeader();
329      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
330        event.push(*itRank,1,msg);
331      client->sendEvent(event);
332    }
333    else client->sendEvent(event);
334  }
335
336  /*!
337    This generic funtion only provides instance for sending, for receving, each
338    child class must define itself.
339    \param [in] id Id of added item
340    \param [in] itemType type of added item
341  */
342  template<class T>
343  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType)
344  {
345    CContext* context = CContext::getCurrent();
346    typedef typename T::EEventId ItemType;
347    if (context->hasClient)
348    {
349      // Use correct context client to send message
350      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
351      for (int i = 0; i < nbSrvPools; ++i)
352      {
353         CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
354         CEventClient event(this->getType(),ItemType(itemType));
355         if (contextClientTmp->isServerLeader())
356         {
357           CMessage msg;
358           msg << this->getId();
359           msg << id;
360           const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
361           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
362             event.push(*itRank,1,msg);
363           contextClientTmp->sendEvent(event);
364         }
365         else contextClientTmp->sendEvent(event);
366      }
367    }
368  }
369
370  template<class T>
371  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType, CContextClient* client)
372  {
373    typedef typename T::EEventId ItemType;
374     CEventClient event(this->getType(),ItemType(itemType));
375     if (client->isServerLeader())
376     {
377       CMessage msg;
378       msg << this->getId();
379       msg << id;
380       const std::list<int>& ranks = client->getRanksServerLeader();
381       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
382         event.push(*itRank,1,msg);
383       client->sendEvent(event);
384     }
385     else client->sendEvent(event);
386  }
387
388
389  template <class T>
390  void CObjectTemplate<T>::recvAttributFromClient(CEventServer& event)
391  {
392
393    CBufferIn* buffer=event.subEvents.begin()->buffer;
394    string id,attrId;
395    *buffer>>id;
396    CAttributeMap & attrMap = *get(id);
397    *buffer>>attrId;
398    CAttribute* attr=attrMap[attrId];
399    info(50) << "attribut recu " << attrId << "  ";
400    if (attr->isEmpty()) info(50) << "--> empty" << endl;
401    else info(50) /*<attr->getValue()*/ << endl;
402    *buffer>>*attr;
403     info(50) << "attribut recu " << attrId << "  ";
404    if (attr->isEmpty()) info(50) << "--> empty" << endl;
405    else info(50) /*attr->getValue()*/ << endl;
406  }
407
408   template <class T>
409   bool CObjectTemplate<T>::dispatchEvent(CEventServer& event)
410   {
411      switch(event.type)
412      {
413         case EVENT_ID_SEND_ATTRIBUTE :
414           recvAttributFromClient(event);
415           return true;
416           break;
417
418         default :
419         return false;
420//           ERROR("void CObjectTemplate<T>::recvEvent(CEventServer& event)", << "Unknown Event");
421      }
422   }
423
424   template <typename T>
425   bool CObjectTemplate<T>::has(const string & id)
426   {
427     return CObjectFactory::HasObject<T>(id);
428   }
429
430   template <typename T>
431   bool CObjectTemplate<T>::has(const string& contextId, const string & id)
432   {
433     return CObjectFactory::HasObject<T>(contextId,id);
434   }
435
436   template <typename T>
437   T* CObjectTemplate<T>::get(const string & id)
438   {
439     return CObjectFactory::GetObject<T>(id).get();
440   }
441
442   template <typename T>
443   T* CObjectTemplate<T>::get(const T* ptr)
444   {
445     return CObjectFactory::GetObject<T>(ptr).get();
446   }
447
448   template <typename T>
449   shared_ptr<T> CObjectTemplate<T>::getShared(const T* ptr)
450   {
451     return CObjectFactory::GetObject<T>(ptr);
452   }
453
454   template <typename T>
455   shared_ptr<T> CObjectTemplate<T>::getShared(void)
456   {
457     return CObjectFactory::GetObject<T>((T*)this);
458   }
459
460   template <typename T>
461   const vector<T*> CObjectTemplate<T>::getAll()
462   {
463     const vector< shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>();
464     vector<T*> vect;
465
466     typename vector<shared_ptr<T> >::const_iterator it;
467     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
468     return vect;
469   }
470
471   template <typename T>
472   const vector<T*> CObjectTemplate<T>::getAll(const string & id)
473   {
474     const vector< shared_ptr<T> >& shared_vect= CObjectFactory::GetObjectVector<T>(id);
475     vector<T*> vect;
476
477     typename vector<shared_ptr<T> >::const_iterator it;
478     for(it=shared_vect.begin();it!=shared_vect.end();++it) vect.push_back(it->get());
479     return vect;
480   }
481
482   template <typename T>
483   T* CObjectTemplate<T>::get(const string& contextId, const string & id)
484   {
485     return CObjectFactory::GetObject<T>(contextId,id).get();
486   }
487
488   template <typename T>
489   T* CObjectTemplate<T>::create(const string & id)
490   {
491     return CObjectFactory::CreateObject<T>(id).get();
492   }   ///--------------------------------------------------------------
493
494  template <typename T>
495  T* CObjectTemplate<T>::get(void)
496  {
497    return CObjectFactory::GetObject<T>((T*)this).get();
498  }
499
500   template <typename T>
501   void CObjectTemplate<T>::generateCInterface(ostream& oss)
502   {
503     string className=getName();
504     int found=className.rfind("_group");
505     if (found!=string::npos) className.replace(found,1,0,'x');
506
507     oss << "/* ************************************************************************** *" << iendl;
508     oss << " *               Interface auto generated - do not modify                     *" << iendl;
509     oss << " * ************************************************************************** */" << iendl;
510     oss << iendl;
511     oss << "#include <boost/multi_array.hpp>" << iendl;
512     oss << "#include <boost/shared_ptr.hpp>" << iendl;
513     oss << "#include \"xios.hpp\"" << iendl;
514     oss << "#include \"attribute_template.hpp\"" << iendl;
515     oss << "#include \"object_template.hpp\"" << iendl;
516     oss << "#include \"group_template.hpp\"" << iendl;
517     oss << "#include \"icutil.hpp\"" << iendl;
518     oss << "#include \"icdate.hpp\"" << iendl;
519     oss << "#include \"timer.hpp\"" << iendl;
520     oss << "#include \"node_type.hpp\"" << iendl;
521     oss << iendl;
522     oss << "extern \"C\"" << iendl;
523     oss << "{" << iendl++;
524     oss << "typedef xios::" << getStrType<T>() << "* " << className << "_Ptr;";
525     SuperClassMap::generateCInterface(oss,className);
526     oss << "}" << iendl--;
527   }
528
529   template <typename T>
530   void CObjectTemplate<T>::generateFortran2003Interface(ostream& oss)
531   {
532     string className=getName();
533     int found=className.rfind("_group");
534     if (found!=string::npos) className.replace(found,1,0,'x');
535
536     oss << "! * ************************************************************************** *" << iendl;
537     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
538     oss << "! * ************************************************************************** *" << iendl;
539     oss << "#include \"../fortran/xios_fortran_prefix.hpp\"" << iendl;
540     oss << iendl;
541     oss << "MODULE " << className << "_interface_attr" << iendl++;
542     oss << "USE, INTRINSIC :: ISO_C_BINDING" << std::endl;
543     oss << iendl;
544     oss << "INTERFACE" << iendl++;
545     oss << "! Do not call directly / interface FORTRAN 2003 <-> C99";
546     SuperClassMap::generateFortran2003Interface(oss,className);
547     oss << iendl--;
548     oss << "END INTERFACE" << iendl--;
549     oss << iendl;
550     oss << "END MODULE " << className << "_interface_attr" << iendl;
551   }
552
553   template <typename T>
554   void CObjectTemplate<T>::generateFortranInterface(ostream& oss)
555   {
556     string className=getName();
557     int found=className.rfind("_group");
558     if (found!=string::npos) className.erase(found,1);
559     string superClassName=getName();
560     found=superClassName.find("_group");
561     if (found!=string::npos) superClassName.erase(found,6);
562
563     oss << "! * ************************************************************************** *" << iendl;
564     oss << "! *               Interface auto generated - do not modify                     *" << iendl;
565     oss << "! * ************************************************************************** *" << iendl;
566     oss << "#include \"xios_fortran_prefix.hpp\"" << iendl;
567     oss << iendl;
568     oss << "MODULE i" << className << "_attr" << iendl++;
569     oss << "USE, INTRINSIC :: ISO_C_BINDING" << iendl;
570     oss << "USE i" << superClassName << iendl;
571     oss << "USE " << className << "_interface_attr" << iendl--;
572//   oss << "TYPE txios(" << className << ")" << iendl;
573//   oss << "  INTEGER(kind = C_INTPTR_T) :: daddr" << iendl;
574//   oss << "END TYPE txios(" << className << ")" << iendl;
575     oss << iendl;
576     oss << "CONTAINS" << iendl;
577     oss << iendl++;
578     SuperClassMap::generateFortranInterface_id(oss,className);
579     oss << iendl;
580     SuperClassMap::generateFortranInterface_hdl(oss,className);
581     oss << iendl;
582     SuperClassMap::generateFortranInterface_hdl_(oss,className);
583     oss << iendl;
584     SuperClassMap::generateFortranInterfaceGet_id(oss,className);
585     oss << iendl;
586     SuperClassMap::generateFortranInterfaceGet_hdl(oss,className);
587     oss << iendl;
588     SuperClassMap::generateFortranInterfaceGet_hdl_(oss,className);
589     oss << iendl;
590     SuperClassMap::generateFortranInterfaceIsDefined_id(oss,className);
591     oss << iendl;
592     SuperClassMap::generateFortranInterfaceIsDefined_hdl(oss,className);
593     oss << iendl;
594     SuperClassMap::generateFortranInterfaceIsDefined_hdl_(oss,className);
595     oss << iendl--;
596     oss << "END MODULE i" << className << "_attr" << iendl;
597   }
598} // namespace xios
599
600#endif // __XIOS_CObjectTemplate_impl__
Note: See TracBrowser for help on using the repository browser.