#include "macro.inc" INCLUDE "xmlioserver.hpp" INCLUDE "attribute_template_impl.hpp" INCLUDE "object_template_impl.hpp" INCLUDE "group_template_impl.hpp" INCLUDE "calendar_type.hpp" #ifdef __cplusplus extern "C" { #endif //__cplusplus typedef xmlioserver::tree::CAxis caxis; typedef xmlioserver::tree::CField cfield; typedef xmlioserver::tree::CDomain cdomain; typedef xmlioserver::tree::CGrid cgrid; typedef xmlioserver::tree::CFile cfile; typedef xmlioserver::tree::CContext ccontext; typedef xmlioserver::tree::CAxisGroup caxisgroup; typedef xmlioserver::tree::CFieldGroup cfieldgroup; typedef xmlioserver::tree::CDomainGroup cdomaingroup; typedef xmlioserver::tree::CGridGroup cgridgroup; typedef xmlioserver::tree::CFileGroup cfilegroup; typedef xmlioserver::tree::CContextGroup ccontextgroup; typedef long int XInt, XSize; // Integer typedef bool XBool; // Logical typedef void * XPtr; // Pointeur C non typé typedef char * XString; // Pointeur C non typé typedef enum { NOTYPE = 0, DTREATMENT/* UNUSED */, DATE, CALENDAR, ECONTEXT, EAXIS, EDOMAIN, EFIELD, EFILE, EGRID, GAXIS, GDOMAIN, GFIELD, GFILE, GGRID } XDType; typedef enum { NETCDF4 = 0 } XFileType; typedef enum { D360 = 0 , ALLLEAP, NOLEAP, JULIAN, GREGORIAN } XCalendarType ; //------------------------------------------------------------------- #define DECLARE_ATTRIBUTE(type, name) \ DECLARE_INTERFACE(axis, type, name) #include "../config/axis_attribute.conf" #undef DECLARE_ATTRIBUTE #define DECLARE_ATTRIBUTE(type, name) \ DECLARE_INTERFACE(field, type, name) #include "../config/field_attribute.conf" #undef DECLARE_ATTRIBUTE #define DECLARE_ATTRIBUTE(type, name) \ DECLARE_INTERFACE(context, type, name) #include "../config/context_attribute.conf" #undef DECLARE_ATTRIBUTE #define DECLARE_ATTRIBUTE(type, name) \ DECLARE_INTERFACE(domain, type, name) #include "../config/domain_attribute.conf" #undef DECLARE_ATTRIBUTE #define DECLARE_ATTRIBUTE(type, name) \ DECLARE_INTERFACE(file, type, name) #include "../config/file_attribute.conf" #undef DECLARE_ATTRIBUTE #define DECLARE_ATTRIBUTE(type, name) \ DECLARE_INTERFACE(grid, type, name) #include "../config/grid_attribute.conf" //------------------------------------------------------------------- #define CASE_ELEM(elem_enum, elem_class) \ case (E##elem_enum): ;; { ;; \ *_ret = (!CObjectFactory::HasObject(__id));; \ ? 0 : CObjectFactory::GetObject(__id).get(); ;; \ return; ;;};; \ case (G##elem_enum): ;; { ;; \ *_ret = (!CObjectFactory::HasObject(__id));; \ ? 0 : CObjectFactory::GetObject(__id).get(); ;;\ return; ;;};; //------------------------------------------------------------------- void xios_handle_create (XPtr * const _ret, XDType _dtype, const XString _id, XSize _id_len) { try { MAKE_STRING(__id, _id, _id_len); switch(_dtype) { case (ECONTEXT): { *_ret = 0; // Si le context n'existe pas, on retourne un handle vide/nul. //*_ret = (!CObjectFactory::HasObject(__id)) // ? 0 : CObjectFactory::GetObject(__id).get(); std::vector > def_vector = CContext::GetContextGroup()->getChildList(); for (StdSize i = 0; i < def_vector.size(); i++) { //std::cout << "_ " << def_vector[i]->getId() << std::endl; if (def_vector[i]->getId().compare(__id) == 0) *_ret = def_vector[i].get(); } //std::cout << __id << "=" << *_ret << std::endl; return ; } CASE_ELEM(AXIS , Axis) CASE_ELEM(DOMAIN , Domain) CASE_ELEM(FIELD , Field) CASE_ELEM(FILE , File) CASE_ELEM(GRID , Grid) default : *_ret = 0; return; } } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } #undef CASE_ELEM //------------------------------------------------------------------- void xios_xml_parse_file (const XString _filename, XSize _filename_len) { try { MAKE_STRING(__filename, _filename, _filename_len) CTreeManager::ParseFile(__filename); //~ StdOStringStream oss; //~ oss << StdString("def_client_pre.") //~ << CMPIManager::GetCommRank(CMPIManager::GetCommWorld()); //~ CTreeManager::PrintTreeToFile(oss.str()); } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_xml_parse_string(const XString _xmlcontent, XSize _xmlcontent_len) { try { MAKE_STRING(__xmlcontent, _xmlcontent, _xmlcontent_len) CTreeManager::ParseString(__xmlcontent); //~ StdOStringStream oss; //~ oss << StdString("def_client_pre.") //~ << CMPIManager::GetCommRank(CMPIManager::GetCommWorld()); //~ CTreeManager::PrintTreeToFile(oss.str()); } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_context_set_current (XPtr const _ctx, bool _wswap) { try { //boost::shared_ptr context = CObjectFactory::GetObject ((CContext*)_ctx); CTreeManager::SetCurrentContextId(((CContext*)_ctx)->getId()); } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_context_create (XPtr * _ctxt, const XString _ctxt_id, XSize _ctxt_id_len, XCalendarType _calType, XInt yr, XInt mth, XInt dd, XInt hr, XInt min, XInt sec) { try { MAKE_STRING(__ctxt_id, _ctxt_id, _ctxt_id_len) boost::shared_ptr context = CTreeManager::CreateContext(__ctxt_id); *_ctxt = context.get(); switch(_calType) { case (D360) : context->setCalendar(boost::shared_ptr (new date::CD360Calendar(yr, mth, dd, hr, min, sec))); break; case (ALLLEAP) : context->setCalendar(boost::shared_ptr (new date::CAllLeapCalendar(yr, mth, dd, hr, min, sec))); break; case (NOLEAP) : context->setCalendar(boost::shared_ptr (new date::CNoLeapCalendar(yr, mth, dd, hr, min, sec))); break; case (JULIAN) : context->setCalendar(boost::shared_ptr (new date::CJulianCalendar(yr, mth, dd, hr, min, sec))); break; case (GREGORIAN): context->setCalendar(boost::shared_ptr (new date::CGregorianCalendar(yr, mth, dd, hr, min, sec))); break; default: std::cerr << "Le calendrier n'est pas identifié" << std::endl; exit (EXIT_FAILURE); } } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- #define CASE_ELEM0(elem_enum, elem_class, group_enum, group_class) \ case (group_enum) : ;; \ { ;; \ group_class * _group = (group_class *) _parent; \ boost::shared_ptr group = ;; \ CObjectFactory::GetObject(_group); ;; \ switch(_child_type) ;; \ { ;; \ case (group_enum) : ;; \ if ((_child_id_len != -1) && ;; \ (CObjectFactory::HasObject(__child_id))) ;; \ return; ;; \ *_child = CGroupFactory::CreateGroup(group, __child_id).get(); ;; \ break; ;; \ case (elem_enum) : ;; \ if ((_child_id_len != -1) && ;; \ (CObjectFactory::HasObject(__child_id))) ;; \ return; ;; \ *_child = CGroupFactory::CreateChild(group, __child_id).get(); ;; \ break; ;; \ default : ;; \ std::cerr << "[xml_tree_add] Type enfant invalide" << std::endl; ;; \ }; ;; \ return; ;; \ } //------------------------------------------------------------------- void xios_xml_tree_add(const XPtr _parent, XDType _parent_type, XPtr * _child, XDType _child_type, const XString _child_id, XSize _child_id_len) { MAKE_STRING(__child_id, _child_id, _child_id_len); try { switch (_parent_type) { case (EFILE) : { CFile * _file = (CFile *) _parent; boost::shared_ptr file = CObjectFactory::GetObject(_file); if (!CObjectFactory::HasObject(file->getId())) file->setVirtualFieldGroup(file->getId()); xios_xml_tree_add (file->getVirtualFieldGroup().get(), GFIELD, _child, EFIELD, _child_id, _child_id_len); return; } CASE_ELEM0(EAXIS , CAxis , GAXIS , CAxisGroup); CASE_ELEM0(EGRID , CGrid , GGRID , CGridGroup); CASE_ELEM0(EDOMAIN, CDomain, GDOMAIN, CDomainGroup); CASE_ELEM0(EFIELD , CField , GFIELD , CFieldGroup); CASE_ELEM0(EFILE , CFile , GFILE , CFileGroup); default : std::cerr << "[xml_tree_add] Type parent invalide" << std::endl; return; } } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } #undef CASE_ELEM0 //------------------------------------------------------------------- void xios_xml_tree_show(const XString _filename, XSize _filename_len) { MAKE_STRING(__filename, _filename, _filename_len); try { if (_filename_len != -1) CTreeManager::PrintTreeToFile(__filename); else CTreeManager::PrintTreeToStream(std::clog); } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_init_ioserver(MPIComm * comm_client) { try { MPIComm comm_client_server, comm_server; CMPIManager::Initialise(NULL, NULL); CMPIManager::DispatchClient(false, *comm_client, comm_client_server, comm_server); } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_dtreatment_start (XPtr const _context, XFileType filetype, MPIComm comm_client_server) { try { CContext * __context = (CContext *) _context; boost::shared_ptr context = CObjectFactory::GetObject(__context); StdOStringStream oss; oss << StdString("def_client_next.") << CMPIManager::GetCommRank(CMPIManager::GetCommWorld()); CTreeManager::PrintTreeToFile(oss.str()); oss.str(""); boost::shared_ptr dt(new CDataTreatment (context)); context->setDataTreatment(dt); oss << StdString("def_client_end.") << CMPIManager::GetCommRank(CMPIManager::GetCommWorld()); CTreeManager::PrintTreeToFile(oss.str()); if ((comm_client_server != -1)) { MPIRequest request = 0; StdOStringStream ostrs; if (CMPIManager::GetCommRank(comm_client_server) == 1) { CTreeManager::ToBinary(ostrs); CLinearBuffer lbuffer(ostrs.str().size()+13); lbuffer.appendString(ostrs.str()); CMPIManager::SendLinearBuffer(comm_client_server, 0, lbuffer, request); CMPIManager::Wait(request); // Pas encore en mode RPC } else { CTreeManager::DomainsToBinary(ostrs); CLinearBuffer lbuffer(ostrs.str().size()+13); lbuffer.appendString(ostrs.str()); CMPIManager::SendLinearBuffer(comm_client_server, 0, lbuffer, request); CMPIManager::Wait(request); // Pas encore en mode RPC } } else { dt->createDataOutput(); } } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_dtreatment_end(void) { try { CMPIManager::Finalize(); } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_write_data(const XString _field_id, XSize _field_id_len, double * data_k8, XSize data_Xsize, XSize data_Ysize, XSize data_Zsize) { MAKE_STRING(__field_id, _field_id, _field_id_len); try { boost::shared_ptr context = CObjectFactory::GetObject(CObjectFactory::GetCurrentContextId()); boost::shared_ptr dtreat = context->getDataTreatment(); if (data_Ysize==-1 && data_Zsize==-1) { ARRAY(double, 1) data(new CArray(boost::extents [data_Xsize])); std::copy(data_k8, data_k8+data->num_elements(), data->data()); dtreat->write_data(__field_id, data); return; } else if (data_Zsize==-1) { ARRAY(double, 2) data(new CArray(boost::extents [data_Xsize][data_Ysize])); std::copy(data_k8, data_k8+data->num_elements(), data->data()); dtreat->write_data(__field_id, data); return; } else { ARRAY(double, 3) data(new CArray(boost::extents [data_Xsize][data_Ysize][data_Zsize])); std::copy(data_k8, data_k8+data->num_elements(), data->data()); dtreat->write_data(__field_id, data); return; } } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_write_data_f(const XString _field_id, XSize _field_id_len, float * data_k4, XSize data_Xsize, XSize data_Ysize, XSize data_Zsize) { MAKE_STRING(__field_id, _field_id, _field_id_len); try { boost::shared_ptr context = CObjectFactory::GetObject(CObjectFactory::GetCurrentContextId()); boost::shared_ptr dtreat = context->getDataTreatment(); if (data_Ysize==-1 && data_Zsize==-1) { ARRAY(float, 1) data(new CArray(boost::extents [data_Xsize])); std::copy(data_k4, &(data_k4[data->num_elements()]), data->data()); dtreat->write_data(__field_id, data); return; } else if (data_Zsize==-1) { ARRAY(float, 2) data(new CArray(boost::extents [data_Xsize][data_Ysize])); std::copy(data_k4, &(data_k4[data->num_elements()]), data->data()); dtreat->write_data(__field_id, data); return; } else { ARRAY(float, 3) data(new CArray(boost::extents [data_Xsize][data_Ysize][data_Zsize])); std::copy(data_k4, &(data_k4[data->num_elements()]), data->data()); dtreat->write_data(__field_id, data); return; } } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_update_calendar(int step) { try { boost::shared_ptr context = CObjectFactory::GetObject(CObjectFactory::GetCurrentContextId()); boost::shared_ptr dtreat = context->getDataTreatment(); dtreat->update_calendar(step); } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- void xios_set_timestep(double ts_year, double ts_month , double ts_day, double ts_hour, double ts_minute, double ts_second) { try { date::CDuration dur = {ts_year, ts_month, ts_day, ts_hour, ts_minute, ts_second}; boost::shared_ptr context = CObjectFactory::GetObject(CObjectFactory::GetCurrentContextId()); boost::shared_ptr dtreat = context->getDataTreatment(); dtreat->set_timestep(dur); } catch (CException & exc) { std::cerr << exc.getMessage() << std::endl; exit (EXIT_FAILURE); } } //------------------------------------------------------------------- #ifdef __cplusplus } #endif //__cplusplus