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 
19 #include <med.h>
20 #include <med_config.h>
21 #include <med_outils.h>
22 #include <hdf5.h>
23 #include <string.h>
24 
_MEDattributeStringWrByName(med_idt pid,const char * const path,const char * const attname,const med_size attsize,const char * const val)25 med_err _MEDattributeStringWrByName(med_idt pid,
26 				    const char * const path,
27 				    const char * const attname,
28 				    const med_size attsize,
29 				    const char * const val)
30 {
31   med_access_mode MED_ACCESS_MODE;
32   med_idt _attid=0,aid=0;
33   med_err _ret=-1;
34   med_idt  type_hdf=0;
35   med_bool        _attmustbecreated= MED_FALSE;
36   hsize_t         _attsize=0;
37   med_size        _valsize=0;
38 
39   if ( (MED_ACCESS_MODE = _MEDmodeAcces(pid) ) == MED_ACC_UNDEF ) {
40     MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_ACCESSMODE, "MED_ACC_UNDEF" );
41     SSCRUTE(attname); SSCRUTE(path);goto ERROR;
42   }
43 
44   _valsize=strlen(val);
45   if (_valsize > attsize) {
46     MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_ATTRIBUTE, attname );
47     ISCRUTE_size(_valsize);ISCRUTE_size(attsize);goto ERROR;
48   }
49 
50   if ((aid = H5Screate(H5S_SCALAR)) < 0){
51     MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_DATASPACE, attname );
52     ISCRUTE_id(aid);
53   }
54 
55   if ( (type_hdf = H5Tcopy(H5T_C_S1)) < 0) {
56     MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_HDFTYPE, MED_ERR_NAME_MSG );
57     SSCRUTE("H5T_C_S1"); goto ERROR;
58   }
59 
60   if ( H5Tset_size(type_hdf,_valsize+1) < 0) {
61     MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_HDFTYPE, MED_ERR_NAME_MSG );
62     SSCRUTE("H5T_C_S1"); goto ERROR;
63   }
64 
65   if  ( (_attid=H5Aopen_by_name( pid, path, attname, H5P_DEFAULT, H5P_DEFAULT ))  >= 0 )
66     if ( MED_ACCESS_MODE == MED_ACC_RDEXT )  {
67       MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_ACCESSMODE, "MED_ACC_RDEXT" );
68       SSCRUTE(attname); SSCRUTE(path);goto ERROR;
69     }
70 
71   if ( _attid > 0 ) {
72     if ( (_attsize=H5Aget_storage_size(_attid) ) < 0 ) goto ERROR;
73     if ( (_valsize+1)  > _attsize ) {
74       if (H5Aclose(_attid) < 0) {
75 	MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_ATTRIBUTE,"");
76 	ISCRUTE_id(_attid);
77 	goto ERROR;
78 	}
79       if ( H5Adelete_by_name(pid,path,attname,H5P_DEFAULT) < 0 ) goto ERROR;
80       _attmustbecreated=MED_TRUE;
81     }
82   }
83 
84   if ( (_attid < 0) || _attmustbecreated )
85     if ( (_attid=H5Acreate_by_name( pid, path, attname, type_hdf, aid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT )) < 0 ) {
86       MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_ATTRIBUTE, attname );
87       SSCRUTE(path);goto ERROR;
88     }
89 
90 
91   if ( H5Awrite(_attid,type_hdf,val) < 0) {
92     MED_ERR_(_ret,MED_ERR_WRITE,MED_ERR_ATTRIBUTE, attname );
93     SSCRUTE(path);goto ERROR;
94   }
95 
96   _ret=0;
97 
98  ERROR:
99 
100   if (type_hdf > 0 ) if ( H5Tclose(type_hdf) < 0) {
101     MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_HDFTYPE, MED_ERR_ID_MSG );
102     ISCRUTE_id(type_hdf);
103   }
104 
105   if (aid > 0 ) if ( H5Sclose(aid) < 0) {
106     MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_DATASPACE, MED_ERR_ID_MSG );
107     ISCRUTE_id(aid);
108   }
109 
110   if (_attid >0) if ( H5Aclose(_attid) < 0) {
111     MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_ATTRIBUTE, MED_ERR_ID_MSG );
112     ISCRUTE_id(_attid);
113   }
114 
115 
116   return _ret;
117 }
118