1 /*  This file is part of MED.
2  *
3  *  COPYRIGHT (C) 1999 - 2019  EDF R&D, CEA/DEN
4  *  MED is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU Lesser General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  MED is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public License
15  *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <med.h>
19 #include <med_config.h>
20 #include <med_outils.h>
21 #include <hdf5.h>
22 #include "med_utils.h"
23 
_MEDdatasetWr(const med_idt id,const char * const datasetname,const med_internal_type datatype,const med_filter * const filter,const void * const value)24 med_err _MEDdatasetWr(const med_idt               id,
25 		      const char * const          datasetname,
26 		      const med_internal_type     datatype,
27 		      const med_filter* const     filter,
28 		      const void * const value) {
29 
30   med_idt         _dataset=0, _dataspace=0,_datadiskspace=0;
31   med_size        _datasetsize[1]={0};
32   med_err         _ret=-1;
33   med_idt         _hdftype=0;
34   int             _datasetsizeEqualTosizespace = 0;
35   med_access_mode _MED_ACCESS_MODE;
36   med_int         _nvaluesperentity=0,_nconstituentpervalue=0;
37   int             _i=0;
38   H5L_info_t      _linkinfo;
39   hsize_t         _dim=0;
40   const void      *_value= value;
41 
42  /*  ISCRUTE((*filter).nentity              ); */
43 /*   ISCRUTE((*filter).nvaluesperentity     ); */
44 /*   ISCRUTE((*filter).nconstituentpervalue ); */
45 /*   ISCRUTE((*filter).constituentselect       ); */
46 /*   ISCRUTE((*filter).switchmode              ); */
47 /*   ISCRUTE((*filter).filterarraysize         ); */
48 /*   ISCRUTE((*filter).profilearraysize        ); */
49 /*   ISCRUTE((*filter).storagemode             ); */
50 /*   SSCRUTE((*filter).profilename             ); */
51 
52 
53   if ( (_MED_ACCESS_MODE = _MEDmodeAcces(id) ) == MED_ACC_UNDEF ) {
54     MED_ERR_(_ret,MED_ERR_UNRECOGNIZED,MED_ERR_ACCESSMODE,MED_ERR_FILE_MSG);
55     goto ERROR;
56   }
57 
58   if ( _MED_ACCESS_MODE == MED_ACC_RDONLY) {
59     MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_ACCESSMODE,MED_ERR_FILE_MSG);
60     ISCRUTE_int(_MED_ACCESS_MODE);
61     goto ERROR;
62   }
63 
64   switch(datatype)
65     {
66     case MED_INTERNAL_FLOAT64 :
67       _hdftype = H5T_NATIVE_DOUBLE;
68       break;
69 
70     case MED_INTERNAL_FLOAT32 :
71       _hdftype = H5T_NATIVE_FLOAT;
72       break;
73 
74     case MED_INT :
75 #if defined(HAVE_F77INT64)
76       _hdftype = H5T_NATIVE_LONG;
77 #else
78       _hdftype = H5T_NATIVE_INT;
79 #endif
80       break;
81 
82     case MED_INTERNAL_INT32 :
83       _hdftype = H5T_NATIVE_INT;
84       break;
85 
86     case MED_INTERNAL_INT64 :
87       /* _hdftype = H5T_NATIVE_LONG; */
88       /* _hdftype = H5T_NATIVE_LLONG; */
89       _hdftype = MED_H5T_INT64;
90       break;
91 
92     case MED_INTERNAL_CHAR:
93       _hdftype = H5T_NATIVE_CHAR;
94       _dim=1;
95       break;
96 
97     case MED_INTERNAL_SNAME:
98       if (!_dim) _dim= MED_SNAME_SIZE;
99     case MED_INTERNAL_NAME:
100       if (!_dim) _dim = MED_NAME_SIZE;
101     case MED_INTERNAL_LNAME:
102       if (!_dim) _dim = MED_LNAME_SIZE;
103 
104 /*       ISCRUTE(_dim); */
105       if( (_hdftype =  H5Tarray_create1( H5T_NATIVE_CHAR, 1, &_dim, 0 )) < 0) {
106 	MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_DATATYPE,"");goto ERROR;
107       }
108       break;
109 
110     default :
111       MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_PARAMETER,MED_ERR_TYPEOF_MSG);
112       ISCRUTE_int(datatype);
113       goto ERROR;
114     }
115 
116   /* Calculate dataset size*/
117   _nvaluesperentity     = (*filter).nvaluesperentity;
118   _nconstituentpervalue = (*filter).nconstituentpervalue;
119   if ( (!_nvaluesperentity)  || (!_nconstituentpervalue) ) {
120     MED_ERR_(_ret,MED_ERR_NOTNULL,MED_ERR_FILTER,"");
121     ISCRUTE((*filter).nvaluesperentity);
122     ISCRUTE((*filter).nconstituentpervalue);
123     goto ERROR;
124   }
125   _datasetsize[0] = (*filter).nvaluesperentity * (*filter).nconstituentpervalue;
126   if ( (*filter).profilearraysize == MED_UNDEF_SIZE ) {
127 /*     if ( ! (*filter).nentity )  { */
128 /*       MED_ERR_(_ret,MED_ERR_NOTNULL,MED_ERR_FILTER,""); */
129 /*       ISCRUTE((*filter).nentity); */
130 /*       goto ERROR; */
131 /*     } */
132     _datasetsize[0]*= (*filter).nentity;
133   }  else
134     _datasetsize[0]*= (*filter).profilearraysize;
135 
136   if ( ! _datasetsize[0] || ! _value) {
137     _dataspace = H5Screate( H5S_NULL );
138     _value=NULL;
139   }
140 
141   if (!_dataspace)
142     if ((_dataspace = H5Screate_simple(1,_datasetsize,NULL)) < 0) {
143       MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_DATASPACE,MED_ERR_SIZE_MSG);
144       ISCRUTE_size(_datasetsize[0]);
145       goto ERROR;
146     }
147 
148   if ( H5Lget_info( id, datasetname,  &_linkinfo, H5P_DEFAULT ) >= 0 ) {
149     if ( _linkinfo.type == H5L_TYPE_SOFT )
150       if ( H5Ldelete(id,datasetname,H5P_DEFAULT) < 0 ) {
151 	MED_ERR_(_ret,MED_ERR_DELETE,MED_ERR_LINK,datasetname);
152 	goto ERROR;
153       }
154   }
155 
156   /* On s'assure de l'existence d'un dataset.
157      S'il n'existe pas, il est crée.
158      S'il existe, le mode MED_ACC_RDEXT génère une erreur.
159      Sinon, sa taille est lue et comparée à la taille du dataspace préalablement crée.
160      Si les tailles sont différente le dataset est supprimé et recrée à la bonne taille.
161   */
162 
163   if ( (_dataset = H5Dopen(id,datasetname)) < 0) {
164 
165     if ((_dataset = H5Dcreate(id,datasetname,_hdftype,_dataspace, H5P_DEFAULT)) < 0) {
166       MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_DATASET,datasetname);
167       goto ERROR;
168     }
169 
170   } else {
171 
172     if ( _MED_ACCESS_MODE == MED_ACC_RDEXT )  {
173       MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_ACCESSMODE,MED_ERR_DATASET_MSG);
174       ISCRUTE_int(_MED_ACCESS_MODE);
175       SSCRUTE(datasetname);
176       goto ERROR;
177     }
178 
179     if ( (_datadiskspace = H5Dget_space(_dataset)) <0 ) {
180       MED_ERR_(_ret,MED_ERR_READ,MED_ERR_DATASPACE,MED_ERR_DATASET_MSG MED_ERR_NAME_MSG );
181       SSCRUTE(datasetname);
182       goto ERROR;
183     }
184 
185     {
186       hsize_t   _sizespace   [H5S_MAX_RANK];
187       hsize_t   _maxsizespace[H5S_MAX_RANK];
188 
189       H5Sget_simple_extent_dims(_datadiskspace, _sizespace, _maxsizespace);
190       _datasetsizeEqualTosizespace = ( (_sizespace[0]) == _datasetsize[0] );
191     }
192 
193     if ( !_datasetsizeEqualTosizespace ) {
194 
195       if ( H5Dclose(_dataset) < 0 ) {
196 	MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_DATASET, datasetname );
197 	goto ERROR;
198       }
199 
200       if ( H5Ldelete(id,datasetname,H5P_DEFAULT)  < 0) {
201 	MED_ERR_(_ret,MED_ERR_DELETE,MED_ERR_DATASET, datasetname );
202 	goto ERROR;
203       }
204       if ( (_dataset = H5Dcreate(id,datasetname,_hdftype,_dataspace,H5P_DEFAULT)) < 0){
205 	MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_DATASET, datasetname );
206 	goto ERROR;
207       }
208 
209     }
210   } /*Fin de traitement d'un dataset existant */
211 
212 
213   if (_value)
214     for (_i=0; _i < (*filter).nspaces; ++_i) {
215       if ( H5Dwrite(_dataset,_hdftype,(*filter).memspace[_i],
216 		    (*filter).diskspace[_i],H5P_DEFAULT, _value) < 0 ) {
217 	MED_ERR_(_ret,MED_ERR_WRITE,MED_ERR_DATASET, datasetname );
218 	ISCRUTE_id(_dataset);
219 	ISCRUTE_int(_i);
220 	ISCRUTE_id((*filter).memspace[_i]);
221 	ISCRUTE_id((*filter).diskspace[_i]);
222 	goto ERROR;
223       }
224     }
225 
226     _ret = 0;
227 
228   ERROR:
229 
230     if ( _dataspace > 0 ) if ( H5Sclose(_dataspace) < 0) {
231       MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_DATASPACE, MED_ERR_ID_MSG );
232       ISCRUTE_id(_dataspace);
233     }
234 
235     if ( _datadiskspace > 0 ) if ( H5Sclose(_datadiskspace) < 0) {
236       MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_DATASPACE, MED_ERR_ID_MSG );
237       ISCRUTE_id(_datadiskspace);
238     }
239 
240     if ( _dataset > 0 ) if ( H5Dclose(_dataset) < 0) {
241       MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_DATASET, MED_ERR_ID_MSG );
242       ISCRUTE_id(_dataset);
243     }
244 
245     if ( _dim > 1 ) if ( H5Tclose(_hdftype) < 0 ) {
246       MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_DATATYPE, MED_ERR_ID_MSG );
247       ISCRUTE_id(_hdftype);
248     }
249 
250     return _ret;
251   }
252