source: XMLIO_V2/dev/common/src/node/file.cpp @ 300

Last change on this file since 300 was 300, checked in by ymipsl, 12 years ago

nouvelle version de developpement de xios

  • nouvelle interface fortran
  • recodage complet de la couche de communication
  • et bien d'autres choses...

YM

File size: 12.2 KB
Line 
1#include "file.hpp"
2
3#include "attribute_template_impl.hpp"
4#include "object_template_impl.hpp"
5#include "group_template_impl.hpp"
6
7#include "object_factory.hpp"
8#include "object_factory_impl.hpp"
9#include "data_output.hpp"
10#include "context.hpp"
11#include "context_server.hpp"
12#include "nc4_data_output.hpp"
13
14
15namespace xmlioserver {
16namespace tree {
17   
18   /// ////////////////////// Définitions ////////////////////// ///
19
20   CFile::CFile(void)
21      : CObjectTemplate<CFile>(), CFileAttributes()
22      , vFieldGroup(), data_out(), enabledFields()
23   { setVirtualFieldGroup() ;}
24
25   CFile::CFile(const StdString & id)
26      : CObjectTemplate<CFile>(id), CFileAttributes()
27      , vFieldGroup(), data_out(), enabledFields()
28   { setVirtualFieldGroup() ;}
29
30   CFile::~CFile(void)
31   { /* Ne rien faire de plus */ }
32
33   ///---------------------------------------------------------------
34
35   StdString CFile::GetName(void)   { return (StdString("file")); }
36   StdString CFile::GetDefName(void){ return (CFile::GetName()); }
37   ENodeType CFile::GetType(void)   { return (eFile); }
38
39   //----------------------------------------------------------------
40
41   boost::shared_ptr<io::CDataOutput> CFile::getDataOutput(void) const
42   {
43      return (data_out);
44   }
45
46   boost::shared_ptr<CFieldGroup> CFile::getVirtualFieldGroup(void) const
47   {
48      return (this->vFieldGroup);
49   }
50
51   std::vector<boost::shared_ptr<CField> > CFile::getAllFields(void) const
52   {
53      return (this->vFieldGroup->getAllChildren());
54   }
55
56   //----------------------------------------------------------------
57
58   std::vector<boost::shared_ptr<CField> > CFile::getEnabledFields
59      (int default_outputlevel, int default_level, bool default_enabled)
60   {
61      if (!this->enabledFields.empty())
62         return (this->enabledFields);
63
64      const int _outputlevel =
65         (!output_level.isEmpty()) ? output_level.getValue() : default_outputlevel;
66      std::vector<boost::shared_ptr<CField> >::iterator it;
67      this->enabledFields = this->getAllFields();
68
69      std::vector<boost::shared_ptr<CField> > newEnabledFields;
70     
71      for ( it = this->enabledFields.begin() ; it != this->enabledFields.end(); it++ )
72      {
73         if (!(*it)->enabled.isEmpty()) // Si l'attribut 'enabled' est défini ...
74         {
75            if (! (*it)->enabled.getValue()) continue;
76//            { it--; this->enabledFields.erase(it+1); continue; }
77         }
78         else // Si l'attribut 'enabled' n'est pas défini ...
79         {
80            if (!default_enabled) continue ;
81//            { it--; this->enabledFields.erase(it+1); continue; }
82         }
83
84         if (!(*it)->level.isEmpty()) // Si l'attribut 'level' est défini ...
85         {
86            if ((*it)->level.getValue() > _outputlevel) continue ;
87//            { it--; this->enabledFields.erase(it+1); continue; }
88         }
89         else // Si l'attribut 'level' n'est pas défini ...
90         {
91            if (default_level > _outputlevel) continue ;
92//            { it--; this->enabledFields.erase(it+1); continue; }
93         }
94 
95//         CField* field_tmp=(*it).get() ;
96//         shared_ptr<CField> sptfield=*it ;
97//         field_tmp->refObject.push_back(sptfield) ;
98         newEnabledFields.push_back(*it) ;
99         // Le champ est finalement actif, on y ajoute sa propre reference.
100         (*it)->refObject.push_back(*it);
101         // Le champ est finalement actif, on y ajoute la référence au champ de base.
102         (*it)->setRelFile(CObjectFactory::GetObject(this));
103         (*it)->baseRefObject->refObject.push_back(*it);
104         // A faire, ajouter les references intermediaires...
105      }
106      enabledFields=newEnabledFields ;
107
108      return (this->enabledFields);
109   }
110
111   //----------------------------------------------------------------
112
113   void CFile::setVirtualFieldGroup(boost::shared_ptr<CFieldGroup> newVFieldGroup)
114   { 
115      this->vFieldGroup = newVFieldGroup; 
116   }
117
118   //----------------------------------------------------------------
119
120   void CFile::setVirtualFieldGroup(void)
121   {
122      this->setVirtualFieldGroup
123         (CObjectFactory::CreateObject<CFieldGroup>());
124   }
125
126   //----------------------------------------------------------------
127
128   void CFile::createHeader(void)
129   {
130   
131      std::vector<boost::shared_ptr<CField> >::iterator it, end = this->enabledFields.end();
132
133      AllDomainEmpty=true ;
134      for (it = this->enabledFields.begin() ;it != end; it++)
135      {
136         boost::shared_ptr<CField> field = *it;
137         AllDomainEmpty&=field->grid->domain->isEmpty() ;
138      }
139     
140      if (!AllDomainEmpty ||  type.getValue()=="one_file")
141      {
142         StdString filename = (!name.isEmpty()) ?   name.getValue() : getId();
143         StdOStringStream oss;
144//         if (! output_dir.isEmpty()) oss << output_dir.getValue();
145         oss << filename;
146         if (!name_suffix.isEmpty()) oss << name_suffix.getValue();
147
148         bool multifile=true ;
149         if (!type.isEmpty())
150         {
151           if (type.getValue()=="one_file") multifile=false ;
152           else if (type.getValue()=="multi_file") multifile=true ;
153           else ERROR("void Context::createDataOutput(void)",
154                      "incorrect file <type> attribut : must be <multi_file> or <one_file>, "
155                      <<"having : <"<<type.getValue()<<">") ;
156         } 
157         
158         shared_ptr<CContext> context=CObjectFactory::GetObject<CContext>(CObjectFactory::GetCurrentContextId()) ;
159         CContextServer* server=context->server ;
160
161         if (multifile) 
162         {
163            if (server->intraCommSize > 1) oss << "_" << server->intraCommRank;
164         }
165         oss << ".nc";
166
167         data_out=shared_ptr<io::CDataOutput>(new io::CNc4DataOutput(oss.str(), false,server->intraComm,multifile));
168
169         data_out->writeFile(CObjectFactory::GetObject<CFile>(this));
170         for (it = this->enabledFields.begin() ;it != end; it++)
171         {
172            boost::shared_ptr<CField> field = *it;
173            this->data_out->writeFieldGrid(field);
174         }
175         
176         for (it = this->enabledFields.begin() ;it != end; it++)
177         {
178            boost::shared_ptr<CField> field = *it;
179            this->data_out->writeField(field);
180         }
181         
182         this->data_out->definition_end();
183      }
184   }
185
186   void CFile::close(void)
187   {
188     if (!AllDomainEmpty ||  type.getValue()=="one_file")
189       this->data_out->closeFile();
190   }
191   //----------------------------------------------------------------
192
193   void CFile::parse(xml::CXMLNode & node)
194   {
195      SuperClass::parse(node);
196      if (node.goToChildElement() & this->hasId())
197      { // Si la définition du fichier intégre des champs et si le fichier est identifié.
198         node.goToParentElement();
199//         this->setVirtualFieldGroup(this->getId());
200         this->getVirtualFieldGroup()->parse(node, false);
201      }
202   }
203   //----------------------------------------------------------------
204
205   StdString CFile::toString(void) const
206   {
207      StdOStringStream oss;
208
209      oss << "<" << CFile::GetName() << " ";
210      if (this->hasId())
211         oss << " id=\"" << this->getId() << "\" ";
212      oss << SuperClassAttribute::toString() << ">" << std::endl;
213      if (this->getVirtualFieldGroup().get() != NULL)
214         oss << *this->getVirtualFieldGroup() << std::endl;
215      oss << "</" << CFile::GetName() << " >";
216      return (oss.str());
217   }
218
219   //----------------------------------------------------------------
220   
221   void CFile::solveDescInheritance(const CAttributeMap * const parent)
222   {
223      SuperClassAttribute::setAttributes(parent);
224      this->getVirtualFieldGroup()->solveDescInheritance(NULL);
225   }
226
227   //----------------------------------------------------------------
228
229   void CFile::solveFieldRefInheritance(void)
230   {
231      // Résolution des héritages par référence de chacun des champs contenus dans le fichier.
232      std::vector<boost::shared_ptr<CField> > allF = this->getAllFields();
233      for (unsigned int i = 0; i < allF.size(); i++)
234         allF[i]->solveRefInheritance();
235   }
236
237   //----------------------------------------------------------------
238
239   void CFile::solveEFGridRef(void)
240   {
241      for (unsigned int i = 0; i < this->enabledFields.size(); i++)
242         this->enabledFields[i]->solveGridReference();
243   }
244
245   //----------------------------------------------------------------
246
247   void CFile::solveEFOperation(void)
248   {
249      for (unsigned int i = 0; i < this->enabledFields.size(); i++)
250         this->enabledFields[i]->solveOperation();
251   }
252   
253   //---------------------------------------------------------------
254   
255   void CFile::toBinary  (StdOStream & os) const
256   {
257      ENodeType genum = CFileGroup::GetType();
258      bool hasVFG = (this->getVirtualFieldGroup().get() != NULL);
259      SuperClass::toBinary(os);
260     
261      os.write (reinterpret_cast<const char*>(&genum) , sizeof(ENodeType));
262      os.write (reinterpret_cast<const char*>(&hasVFG) , sizeof(bool));
263     
264      if (hasVFG)this->getVirtualFieldGroup()->toBinary(os);
265         
266   }
267   
268   //----------------------------------------------------------------
269   
270   void CFile::fromBinary(StdIStream & is)
271   {
272      ENodeType renum = Unknown;
273      bool hasVFG = false;
274      SuperClass::fromBinary(is);
275     
276      is.read (reinterpret_cast<char*>(&renum), sizeof(ENodeType));
277      is.read (reinterpret_cast<char*>(&hasVFG), sizeof(bool));
278     
279      if (renum != CFileGroup::GetType())
280         ERROR("CFile::fromBinary(StdIStream & is)",
281               << "[ renum = " << renum << "] Bad type !");
282     
283//      this->setVirtualFieldGroup(this->getId());
284      if (hasVFG)this->getVirtualFieldGroup()->fromBinary(is);
285     
286   }
287   
288   shared_ptr<CField> CFile::addField(const string& id)
289   {
290     return vFieldGroup->createChild(id) ;
291   }
292
293   shared_ptr<CFieldGroup> CFile::addFieldGroup(const string& id)
294   {
295     return vFieldGroup->createChildGroup(id) ;
296   }
297   
298 
299   void CFile::sendAddField(const string& id)
300   {
301    shared_ptr<CContext> context=CContext::current() ;
302   
303    if (! context->hasServer )
304    {
305       CContextClient* client=context->client ;
306
307       CEventClient event(this->getType(),EVENT_ID_ADD_FIELD) ;   
308       if (client->isServerLeader())
309       {
310         CMessage msg ;
311         msg<<this->getId() ;
312         msg<<id ;
313         event.push(client->getServerLeader(),1,msg) ;
314         client->sendEvent(event) ;
315       }
316       else client->sendEvent(event) ;
317    }
318     
319   }
320   
321   void CFile::sendAddFieldGroup(const string& id)
322   {
323    shared_ptr<CContext> context=CContext::current() ;
324    if (! context->hasServer )
325    {
326       CContextClient* client=context->client ;
327
328       CEventClient event(this->getType(),EVENT_ID_ADD_FIELD_GROUP) ;   
329       if (client->isServerLeader())
330       {
331         CMessage msg ;
332         msg<<this->getId() ;
333         msg<<id ;
334         event.push(client->getServerLeader(),1,msg) ;
335         client->sendEvent(event) ;
336       }
337       else client->sendEvent(event) ;
338    }
339     
340   }
341   
342   void CFile::recvAddField(CEventServer& event)
343   {
344     
345      CBufferIn* buffer=event.subEvents.begin()->buffer;
346      string id;
347      *buffer>>id ;
348      get(id)->recvAddField(*buffer) ;
349   }
350   
351   
352   void CFile::recvAddField(CBufferIn& buffer)
353   {
354      string id ;
355      buffer>>id ;
356      addField(id) ;
357   }
358
359   void CFile::recvAddFieldGroup(CEventServer& event)
360   {
361     
362      CBufferIn* buffer=event.subEvents.begin()->buffer;
363      string id;
364      *buffer>>id ;
365      get(id)->recvAddFieldGroup(*buffer) ;
366   }
367   
368   
369   void CFile::recvAddFieldGroup(CBufferIn& buffer)
370   {
371      string id ;
372      buffer>>id ;
373      addFieldGroup(id) ;
374   }
375   
376
377   bool CFile::dispatchEvent(CEventServer& event)
378   {
379      if (SuperClass::dispatchEvent(event)) return true ;
380      else
381      {
382        switch(event.type)
383        {
384           case EVENT_ID_ADD_FIELD :
385             recvAddField(event) ;
386             return true ;
387             break ;
388         
389           case EVENT_ID_ADD_FIELD_GROUP :
390             recvAddFieldGroup(event) ;
391             return true ;
392             break ;       
393         
394           default :
395              ERROR("bool CFile::dispatchEvent(CEventServer& event)", <<"Unknown Event") ;
396           return false ;
397        }
398      }
399   }
400   
401   
402   
403   
404   ///---------------------------------------------------------------
405
406} // namespace tree
407} // namespace xmlioserver
Note: See TracBrowser for help on using the repository browser.