source: XMLIO_V2/dev/dev_rv/src/XMLIO/c_interface.cpp @ 138

Last change on this file since 138 was 138, checked in by hozdoba, 14 years ago

Mise à jour

File size: 19.5 KB
Line 
1#include "c_interface.hpp"
2
3/* ********************************************************** */
4/*                      HANDLE INTERFACE                      */
5/* ********************************************************** */
6
7#define CASE_ELEM(elem_enum, elem_class)                    \
8         case (E##elem_enum):                               \
9            *_ret = (!C##elem_class::HasObject(__id)) ?     \
10               0 : C##elem_class::GetObject(__id);          \
11            return;                                         \
12         case (G##elem_enum):                               \
13            *_ret = (!elem_class##Group::HasObject(__id)) ? \
14               0 : elem_class##Group::GetObject(__id);      \
15            return;
16
17void xios_handle_create (XPtr * const _ret, XDType _dtype,
18                         const XString _id, XSize _id_len)
19{
20   MAKE_STRING(__id, _id, _id_len);
21   switch(_dtype)
22   {
23      case (ECONTEXT):
24         // Si le context n'existe pas, on retourne un handle vide/nul.
25         *_ret = (!Context::HasContext(__id)) ? 0 : Context::GetContext(__id) ;
26         return ;
27      CASE_ELEM(AXIS   , Axis);
28      CASE_ELEM(DOMAIN , Domain);
29      CASE_ELEM(FIELD  , Field);
30      CASE_ELEM(FILE   , File);
31      CASE_ELEM(GRID   , Grid);
32      default :
33         *_ret = 0;
34         return ;
35   };
36}
37
38#undef CASE_ELEM
39
40/* ********************************************************** */
41/*                      XML INTERFACE                         */
42/* ********************************************************** */
43
44void xios_xml_parse_file(const XString _filename, XSize _filename_len)
45{
46
47      MAKE_STRING(__filename, _filename, _filename_len);
48      std::ifstream __istr( __filename.c_str() , std::ifstream::in );
49
50      // On commence la lecture du flux de donnée xml.
51      XMLNode node = XMLNode::CreateNode(__istr, Context::GetRootName());
52      // On parse le fichier xml noeud par noeud
53      // (ie on construit dynamiquement notre arbre d'objets).
54      XMLParser::Parse(node);
55}
56
57void xios_xml_parse_string(const XString _xmlcontent, XSize _xmlcontent_len)
58{
59   MAKE_STRING(__xmlcontent, _xmlcontent, _xmlcontent_len);
60   std::istringstream __istr(__xmlcontent);
61
62   // On commence la lecture du flux de donnée xml.
63   XMLNode node = XMLNode::CreateNode(__istr, Context::GetRootName());
64   // On parse le document xml noeud par noeud
65   XMLParser::Parse(node);
66}
67/* ********************************************************** */
68/*                      CONTEXT INTERFACE                     */
69/* ********************************************************** */
70
71void xios_context_set_current (XPtr _ctx, bool _wswap)
72{
73   Context* const __ctxt = (Context*) _ctx;
74   Context::SetCurrentContext(__ctxt->getId(), _wswap) ;
75}
76
77void xios_context_create (XPtr * _ctx, const XString _ctx_id,
78                          XSize _ctx_id_len, XCalendarType _calType,
79                          XInt yr, XInt mth, XInt dd,
80                          XInt hr, XInt min, XInt sec)
81{
82   MAKE_STRING(__ctx_id, _ctx_id, _ctx_id_len);
83   // si le contexte existe déjà, on arrête le traitement.
84   if (Context::HasContext(__ctx_id)) { _ctx = NULL; return ; }
85
86   Context::SetCurrentContext(__ctx_id, false, false);
87   Context * context = Context::CreateObject(__ctx_id);
88   context->createDefinitions(); *_ctx = context;
89
90   if (!Context::HasContext(__ctx_id)) // Au cas où ...
91      std::cerr << "La création du contexte a échoué ???" << std::endl;
92
93   switch(_calType)
94   {
95      case (D360) :
96         context->setCalendar(new D360Calendar(yr, mth, dd, hr, min, sec));
97         return;
98      case (ALLLEAP) :
99         context->setCalendar(new AllLeapCalendar(yr, mth, dd, hr, min, sec));
100         return;
101      case (NOLEAP) :
102         context->setCalendar(new NoLeapCalendar(yr, mth, dd, hr, min, sec));
103         return;
104      case (JULIAN) :
105         context->setCalendar(new JulianCalendar(yr, mth, dd, hr, min, sec));
106         return;
107      case (GREGORIAN) :
108         context->setCalendar(new GregorianCalendar(yr, mth, dd, hr, min, sec));
109         return;
110      default:
111         std::cerr << "[context_create] Type de calendrier invalide [0-5]" << std::endl;
112         return;
113   }
114}
115
116/* ********************************************************** */
117/*                    XML TREE INTERFACE                      */
118/* ********************************************************** */
119
120#define CASE_ELEM0(elem_enum, elem_class, group_enum, group_class)              \
121      case (group_enum) : {                                                     \
122         group_class * _group = (group_class *) _parent;                        \
123         switch(_child_type) {                                                  \
124            case (group_enum) :                                                 \
125               if ((_child_id_len != -1) &&                                     \
126                   (group_class::HasObject(___child_id))) return;               \
127               *_child = (_child_id_len != -1)                                  \
128                       ? (group_class *)(&_group->createGroup(___child_id))     \
129                       : (group_class *)(&_group->createGroup());               \
130               break;                                                           \
131            case (elem_enum) :                                                  \
132               if ((_child_id_len != -1) &&                                     \
133                   (elem_class::HasObject(___child_id))) return;                \
134               *_child = (_child_id_len != -1)                                  \
135                       ? (elem_class *)(&_group->createChild(___child_id))      \
136                       : (elem_class *)(&_group->createChild());                \
137               break;                                                           \
138            default :                                                           \
139               std::cerr << "[xml_tree_add] Type enfant invalide" << std::endl; \
140         }; return; }
141
142void xios_xml_tree_add (const XPtr _parent, XDType _parent_type, XPtr * _child,
143                        XDType _child_type, const XString _child_id, XSize _child_id_len)
144{
145   string ___child_id;
146   if (_child_id_len != -1)
147   {
148      MAKE_STRING(__child_id, _child_id, _child_id_len);
149      ___child_id = __child_id;
150   }
151
152   switch (_parent_type)
153   {
154      case (EFILE) :
155      {
156         CFile * _file = (CFile *) _parent;
157         FieldGroup * _field_group = _file->createVirtualFieldGroup(_file->getId());
158         xios_xml_tree_add (_field_group, GFIELD,
159                            _child, _child_type, _child_id, _child_id_len);
160         return;
161      }
162      CASE_ELEM0(EAXIS, CAxis, GAXIS, AxisGroup);
163      CASE_ELEM0(EGRID, CGrid, GGRID, GridGroup);
164      CASE_ELEM0(EDOMAIN, CDomain, GDOMAIN, DomainGroup);
165      CASE_ELEM0(EFIELD, CField, GFIELD, FieldGroup);
166      CASE_ELEM0(EFILE, CFile, GFILE, FileGroup);
167      default :
168         std::cerr << "[xml_tree_add] Type parent invalide" << std::endl;
169         return;
170   }
171}
172
173#undef CASE_ELEM0
174
175void xios_xml_tree_show(const XString _filename, XSize _filename_len)
176{
177   string ___filename;
178   if (_filename_len != -1)
179   {
180      MAKE_STRING(__filename, _filename, _filename_len);
181      ___filename = __filename;
182   }
183   if (_filename_len == -1)
184      // On écrit l'arborescence résultante du traitement sur la sortie de log.
185      Context::ShowTree(std::clog);
186   else
187   {
188      std::ofstream __outfile (___filename.c_str());
189      // On écrit l'arborescence résultante du traitement dans le fichier.
190      Context::ShowTree(__outfile);
191      __outfile.close();
192   }
193}
194
195#undef XML_SET
196#undef XML_SET_STRING
197
198#define XML_SET(ttype, type, type_var, var, long_var)                 \
199   void xios_xml_set_##type##_##var                                   \
200                  (XPtr const _##type, XDType _dtype, type_var var){  \
201      if (_dtype >= 10 && _dtype <= 14) {                             \
202         ttype##Group * __##type = (ttype##Group *) _##type;          \
203         __##type->set_##long_var(var);                               \
204      } else {                                                        \
205         C##ttype * __##type = (C##ttype *) _##type;                  \
206         __##type->set_##long_var(var);                               \
207   }}
208
209
210#define XML_SET_STRING(ttype, type, var, long_var)              \
211   void xios_xml_set_##type##_##var(XPtr const _##type,         \
212      XDType _dtype, const XString _##var, XSize _##var##_len) {\
213      MAKE_STRING(___##var, _##var, _##var##_len);              \
214      if (_dtype >= 10 && _dtype <= 14) {                       \
215         ttype##Group * __##type = (ttype##Group *) _##type;    \
216         __##type->set_##long_var(___##var);                    \
217      } else {                                                  \
218         C##ttype * __##type = (C##ttype *) _##type;            \
219         __##type->set_##long_var(___##var);                    \
220   }}
221
222// Attributs de field ou field_group //
223XML_SET_STRING(Field, field, name, name)
224XML_SET_STRING(Field, field, sname, standard_name)
225XML_SET_STRING(Field, field, lname, long_name)
226XML_SET_STRING(Field, field, unit, unit)
227XML_SET_STRING(Field, field, operation, operation)
228
229void xios_xml_set_field_freq_op(XPtr const _field, XDType _dtype,
230                                double year, double month, double day,
231                                double hour, double minute, double second)
232{
233   const Duration _dur   = {year, month, day, hour, minute, second};
234   if (_dtype >= 10 && _dtype <= 14)
235   {
236      FieldGroup * __field = (FieldGroup *) _field;
237      __field->set_freq_op(_dur);
238   } else {
239      CField * __field = (CField *) _field;
240      __field->set_freq_op(_dur);
241   }
242}
243
244XML_SET(Field, field, int, level, level)
245XML_SET(Field, field, int, prec, prec)
246XML_SET(Field, field, bool, enabled, enabled)
247
248XML_SET_STRING(Field, field, dref, domain_ref)
249XML_SET_STRING(Field, field, aref, axis_ref)
250XML_SET_STRING(Field, field, gref, grid_ref)
251XML_SET_STRING(Field, field, zref, zoom_ref)
252XML_SET_STRING(Field, field, fref, field_ref)
253
254// Attributs de file ou file_group
255XML_SET_STRING(File, file, name, name)
256XML_SET_STRING(File, file, description, description)
257
258void xios_xml_set_file_output_freq(XPtr const _file, XDType _dtype,
259                                   double year, double month, double day,
260                                   double hour, double minute, double second)
261{
262   const Duration _dur   = {year, month, day, hour, minute, second};
263   if (_dtype >= 10 && _dtype <= 14)
264   {
265      FileGroup * __file = (FileGroup *) _file;
266      __file->set_output_freq(_dur);
267   } else {
268      CFile * __file= (CFile *) _file;
269      __file->set_output_freq(_dur);
270   }
271}
272
273XML_SET(File, file, int, olevel, output_level)
274XML_SET(File, file, bool, enabled, enabled)
275
276// Attributs de grid ou grid_group
277XML_SET_STRING(Grid, grid, name, name)
278XML_SET_STRING(Grid, grid, description, description)
279XML_SET_STRING(Grid, grid, dref, domain_ref)
280XML_SET_STRING(Grid, grid, aref, axis_ref)
281
282// Attribut de axis ou axis group
283XML_SET_STRING(Axis, axis, name, name)
284XML_SET_STRING(Axis, axis, sname, standard_name)
285XML_SET_STRING(Axis, axis, lname, long_name)
286
287XML_SET_STRING(Axis, axis, unit, unit)
288
289void xios_xml_set_axis_value(XPtr const _axis, XDType _dtype,
290                             double value[], XSize value_size)
291{
292   Array<double, 1> __arr(value, shape(value_size), neverDeleteData, FortranArray<1>());
293   if (_dtype >= 10 && _dtype <= 14)
294   {
295      AxisGroup * __axis = (AxisGroup *) _axis;
296      __axis->set_size(value_size);
297      __axis->zvalue.getValue()->resize(value_size);
298      __axis->set_zvalue(__arr);
299   } else {
300      CAxis * __axis = (CAxis *) _axis;
301      __axis->set_size(value_size);
302      __axis->zvalue.getValue()->resize(value_size);
303      __axis->set_zvalue(__arr);
304   }
305}
306
307// Attribut de domain ou domain_group
308XML_SET_STRING(Domain, domain, name, name)
309XML_SET_STRING(Domain, domain, sname, standard_name)
310XML_SET_STRING(Domain, domain, lname, long_name)
311
312XML_SET(Domain, domain, int, niglo, ni_glo)
313XML_SET(Domain, domain, int, njglo, nj_glo)
314
315XML_SET(Domain, domain, int, ibegin, ibegin)
316XML_SET(Domain, domain, int, iend, iend)
317XML_SET(Domain, domain, int, ni, ni)
318
319XML_SET(Domain, domain, int, jbegin, jbegin)
320XML_SET(Domain, domain, int, jend, jend)
321XML_SET(Domain, domain, int, nj, nj)
322
323void xios_xml_set_domain_mask(XPtr const _domain, XDType _dtype, bool * _mask ,
324                              XSize _maskXsize, XSize _maskYsize)
325{
326   Array<bool, 2> __arr(_mask, shape(_maskXsize, _maskYsize), neverDeleteData, FortranArray<2>());
327   if (_dtype >= 10 && _dtype <= 14)
328   {
329      DomainGroup * __domain = (DomainGroup *) _domain;
330      __domain->mask.getValue()->resize(shape(_maskXsize, _maskYsize));
331      __domain->set_mask(__arr);
332   } else {
333      CDomain * __domain = (CDomain *) _domain;
334      __domain->mask.getValue()->resize(shape(_maskXsize, _maskYsize));
335      __domain->set_mask(__arr);
336   }
337
338}
339
340XML_SET(Domain, domain, int, ddim, data_dim)
341XML_SET(Domain, domain, int, dni, data_ni)
342XML_SET(Domain, domain, int, dnj, data_nj)
343XML_SET(Domain, domain, int, dibegin, data_ibegin)
344XML_SET(Domain, domain, int, djbegin, data_jbegin)
345
346XML_SET(Domain, domain, int, dnindex, data_n_index)
347
348void xios_xml_set_domain_diindex(XPtr const _domain, XDType _dtype,
349                                 int _diindex[], XSize _diindex_size)
350{
351   Array<int, 1> __arr(_diindex, shape(_diindex_size), neverDeleteData, FortranArray<1>());
352   if (_dtype >= 10 && _dtype <= 14)
353   {
354      DomainGroup * __domain = (DomainGroup *) _domain;
355      __domain->data_i_index.getValue()->resize(_diindex_size);
356      __domain->set_data_i_index(__arr);
357   } else {
358      CDomain * __domain = (CDomain *) _domain;
359      __domain->data_i_index.getValue()->resize(_diindex_size);
360      __domain->set_data_i_index(__arr);
361   }
362}
363
364void xios_xml_set_domain_djindex(XPtr const _domain, XDType _dtype,
365                                 int _djindex[], XSize _djindex_size)
366{
367   Array<int, 1> __arr(_djindex, shape(_djindex_size), neverDeleteData, FortranArray<1>());
368   if (_dtype >= 10 && _dtype <= 14)
369   {
370      DomainGroup * __domain = (DomainGroup *) _domain;
371      __domain->data_j_index.getValue()->resize(_djindex_size);
372      __domain->set_data_j_index(__arr);
373   } else {
374      CDomain * __domain = (CDomain *) _domain;
375      __domain->data_j_index.getValue()->resize(_djindex_size);
376      __domain->set_data_j_index(__arr);
377   }
378}
379
380void xios_xml_set_domain_lonvalue(XPtr const _domain, XDType _dtype, double _lonvalue[],
381                                  XSize _lonvalue_Xsize, XSize _lonvalue_Ysize)
382{
383   XSize __size = (_lonvalue_Ysize == -1)
384                  ? _lonvalue_Xsize : (_lonvalue_Ysize*_lonvalue_Xsize);
385   Array<double, 1> __arr(_lonvalue, shape(__size), neverDeleteData, FortranArray<1>());
386   if (_dtype >= 10 && _dtype <= 14)
387   {
388      DomainGroup * __domain = (DomainGroup *) _domain;
389      __domain->lonvalue.getValue()->resize(__size);
390      __domain->set_lonvalue(__arr);
391   } else {
392      CDomain * __domain = (CDomain *) _domain;
393      __domain->lonvalue.getValue()->resize(__size);
394      __domain->set_lonvalue(__arr);
395   }
396}
397
398void xios_xml_set_domain_latvalue(XPtr const _domain, XDType _dtype, double _latvalue[],
399                                  XSize _latvalue_Xsize, XSize _latvalue_Ysize)
400{
401   XSize __size = (_latvalue_Ysize == -1)
402                  ? _latvalue_Xsize : (_latvalue_Ysize*_latvalue_Xsize);
403   Array<double, 1> __arr(_latvalue, shape(__size), neverDeleteData, FortranArray<1>());
404   if (_dtype >= 10 && _dtype <= 14)
405   {
406      DomainGroup * __domain = (DomainGroup *) _domain;
407      __domain->latvalue.getValue()->resize(__size);
408      __domain->set_latvalue(__arr);
409   } else {
410      CDomain * __domain = (CDomain *) _domain;
411      __domain->latvalue.getValue()->resize(__size);
412      __domain->set_latvalue(__arr);
413   }
414}
415
416XML_SET_STRING(Domain, domain, domtype, domtype)
417
418/* ********************************************************** */
419/*                   DATA TREATMENT INTERFACE                 */
420/* ********************************************************** */
421static std::vector<DataTreatment *> AllDataTreatment;
422
423static void deleteAllDataTreatment(void)
424{
425   std::vector<DataTreatment *>::iterator it;
426   for (it  = AllDataTreatment.begin();
427        it != AllDataTreatment.end(); it++)
428      if (*it != NULL) delete (*it);
429}
430
431void xios_dtreatment_start(XPtr const _context, XFileType filetype)
432{
433   static bool called = false;
434   Context       * const __ctxt = (Context *) _context;
435   DataTreatment * const __dtrt =__ctxt->setDataTreatment<DataTreatment>();
436   if (__dtrt != NULL)
437   {
438      AllDataTreatment.push_back(__dtrt);
439      if (!called)
440      {
441         atexit (&deleteAllDataTreatment);
442         called = true;
443      }
444      switch(filetype)
445      {
446         case (NETCDF4):
447            __dtrt->createDataOutput<NetCDF4DataOutput>();
448            return;
449         // Autres formats de fichiers si disponibles...
450         default:
451            return;
452      }
453   }
454}
455
456void xios_dtreatment_end(void)
457{
458
459
460}
461
462void xios_write_data(const XString _field_id, XSize _field_id_len, double * data_k8,
463                     XSize data_Xsize, XSize data_Ysize, XSize data_Zsize)
464{
465   MAKE_STRING(__field_id, _field_id, _field_id_len);
466
467   Context          * const __ctxt = Context::GetCurrentContext();
468   DataTreatment    * __dtrt = __ctxt->getDataTreatment();
469   AbstractCalendar * __cald = __ctxt->getCalendar();
470   if (__dtrt != NULL)
471   {
472      std::cout << "> Itération de calcul effectuée à  la date t = " << __cald->getCurrentDate()
473                << " (soit aprÚs " << (Time)__cald->getCurrentDate() << " sec.)." << std::endl;
474      std::cout << __field_id << " : "
475                << data_Xsize << " : "
476                << data_Ysize << " : "
477                << data_Zsize << std::endl;
478      if ((data_Zsize == -1) && (data_Ysize == -1))
479      { // cas 1D
480         Array<double, 1> __arr(data_k8, shape(data_Xsize),
481                                neverDeleteData, FortranArray<1>());
482         __dtrt->writeData<Array<double, 1> >(__field_id, __arr);
483      }
484      else if (data_Zsize == -1)
485      { // cas 2D
486         Array<double, 2> __arr(data_k8, shape(data_Xsize, data_Ysize),
487                                neverDeleteData, FortranArray<2>());
488         __dtrt->writeData<Array<double, 2> >(__field_id, __arr);
489      }
490      else
491      { // cas 3D
492         Array<double, 3> __arr(data_k8, shape(data_Xsize, data_Ysize, data_Zsize),
493                                neverDeleteData, FortranArray<3>());
494         __dtrt->writeData<Array<double, 3> >(__field_id, __arr);
495      }
496   }
497}
498
499/* ********************************************************** */
500/*                      CALENDAR INTERFACE                    */
501/* ********************************************************** */
502
503void xios_update_calendar(int step)
504{
505   Context * current = Context::GetCurrentContext();
506   AbstractCalendar * calendar =  current->getCalendar();
507   if (current->getDataTreatment() == NULL)
508   {
509      std::cerr << "Error : Le traitement n'a pas été effectué" << std::endl;
510      return;
511   }
512   calendar->update();
513}
514
515void xios_set_timestep(double ts_year, double ts_month, double ts_day,
516                       double ts_hour, double ts_minute, double ts_second)
517{
518   Context * current = Context::GetCurrentContext();
519   AbstractCalendar * calendar =  current->getCalendar();
520   struct _duration dr = { ts_year, ts_month , ts_day,
521                           ts_hour, ts_minute, ts_second };
522   if (current->getDataTreatment() == NULL)
523   {
524      std::cerr << "Error : Le traitement n'a pas été effectué" << std::endl;
525      return;
526   }
527   calendar->setTimeStep(dr);
528}
529
530#undef XML_SET
531#undef XML_SET_STRING
532#undef isNullHandle
Note: See TracBrowser for help on using the repository browser.