fix hdf5 locked file by listvar_in_hdf5 and import_from_hdf5 functions
[scilab.git] / scilab / modules / hdf5 / src / c / h5_fileManagement.c
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2010 - DIGITEO - Allan CORNET
4 *  Copyright (C) 2012 - Scilab Enterprises - Antoine ELIAS
5 *
6 *  This file must be used under the terms of the CeCILL.
7 *  This source file is licensed as described in the file COPYING, which
8 *  you should have received as part of this distribution.  The terms
9 *  are also available at
10 *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11 *
12 */
13 /*--------------------------------------------------------------------------*/
14 #include <hdf5.h>
15 #include <string.h>
16 #include "h5_fileManagement.h"
17 #include "FileExist.h"
18 #include "deleteafile.h"
19 #include "isdir.h"
20 #include "splitpath.h"
21 #include "scicurdir.h"
22 #include "MALLOC.h"
23 #ifdef _MSC_VER
24 #include "strdup_windows.h"
25 #endif
26 /*--------------------------------------------------------------------------*/
27 static char *getPathFilename(char *fullfilename);
28 static char *getFilenameWithExtension(char *fullfilename);
29 /*--------------------------------------------------------------------------*/
30 int createHDF5File(char *name)
31 {
32     hid_t       file;
33     hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);
34     char *pathdest = getPathFilename(name);
35     char *currentpath = NULL;
36     char *filename = getFilenameWithExtension(name);
37     int ierr = 0;
38
39     //H5Pset_fclose_degree(fapl, H5F_CLOSE_STRONG);
40
41     /* TO DO : remove when HDF5 will be fixed ... */
42     /* HDF5 does not manage no ANSI characters */
43     /* UGLY workaround :( */
44     /* We split path, move in this path, open file */
45     /* and return in previous place */
46     /* see BUG 6440 */
47     currentpath = scigetcwd(&ierr);
48
49     //prevent error msg to change directory to ""
50     if (strcmp(pathdest, "") != 0)
51     {
52         scichdir(pathdest);
53     }
54
55     FREE(pathdest);
56     /*bug 5629 : to prevent replace directory by file*/
57     if (isdir(filename))
58     {
59         FREE(filename);
60         FREE(currentpath);
61         return -2;
62     }
63
64     if (FileExist(filename))
65     {
66         deleteafile(filename);
67     }
68     /*
69     * Create a new file using the default properties.
70     */
71
72     file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
73
74     scichdir(currentpath);
75
76     FREE(currentpath);
77     FREE(filename);
78
79     return file;
80 }
81 /*--------------------------------------------------------------------------*/
82 int openHDF5File(char *name, int _iAppendMode)
83 {
84     hid_t           file;
85     char *pathdest = getPathFilename(name);
86     char *currentpath = NULL;
87     char *filename = getFilenameWithExtension(name);
88     int ierr = 0;
89     void *oldclientdata = NULL;
90     /* Used to avoid stack trace to be displayed */
91     H5E_auto2_t oldfunc;
92
93     /* TO DO : remove when HDF5 will be fixed ... */
94     /* HDF5 does not manage no ANSI characters */
95     /* UGLY workaround :( */
96     /* We split path, move in this path, open file */
97     /* and return in previous place */
98     /* see BUG 6440 */
99     currentpath = scigetcwd(&ierr);
100
101     //prevent error msg to change directory to ""
102     if (strcmp(pathdest, "") != 0)
103     {
104         scichdir(pathdest);
105     }
106
107     /* Save old error handler */
108     H5Eget_auto2(H5E_DEFAULT, &oldfunc, &oldclientdata);
109
110     /* Turn off error handling */
111     H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
112
113     if (_iAppendMode == 0)
114     {
115         //read only
116         file = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
117     }
118     else
119     {
120         //read write to append
121         file = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT);
122     }
123
124     /* The following test will display the backtrace in case of error */
125     /* Deactivated because displayed each time we call 'load' to open a non-HDF5 file */
126     /*if (file < 0)
127     {
128         H5Eprint(stderr);
129         }*/
130     /* Restore previous error handler */
131     H5Eset_auto2(H5E_DEFAULT, oldfunc, oldclientdata);
132
133     scichdir(currentpath);
134
135     if (currentpath)
136     {
137         FREE(currentpath);
138         currentpath = NULL;
139     }
140     if (filename)
141     {
142         FREE(filename);
143         filename = NULL;
144     }
145     if (pathdest)
146     {
147         FREE(pathdest);
148         pathdest = NULL;
149     }
150
151     return file;
152 }
153 /*--------------------------------------------------------------------------*/
154 int isHDF5File(char* _pstFilename)
155 {
156     int iRet = 0;
157     char *pathdest = getPathFilename(_pstFilename);
158     char *currentpath = NULL;
159     char *filename = getFilenameWithExtension(_pstFilename);
160     int ierr = 0;
161
162     /* TO DO : remove when HDF5 will be fixed ... */
163     /* HDF5 does not manage no ANSI characters */
164     /* UGLY workaround :( */
165     /* We split path, move in this path, open file */
166     /* and return in previous place */
167     /* see BUG 6440 */
168     currentpath = scigetcwd(&ierr);
169     {
170
171         //prevent error msg to change directory to ""
172         if (strcmp(pathdest, "") != 0)
173         {
174             scichdir(pathdest);
175         }
176         FREE(pathdest);
177
178         iRet = H5Fis_hdf5(filename);
179         FREE(filename);
180     }
181     scichdir(currentpath);
182     FREE(currentpath);
183
184     return iRet > 0 ? 1 : 0;
185 }
186
187 void closeHDF5File(int file)
188 {
189     herr_t status                                       = 0;
190
191     /* printf("Open groups: %d\n", H5Fget_obj_count(file, H5F_OBJ_GROUP));
192     printf("Open datasets: %d\n", H5Fget_obj_count(file, H5F_OBJ_DATASET));
193     printf("Open datatypes: %d\n", H5Fget_obj_count(file, H5F_OBJ_DATATYPE));
194     printf("Open attributes: %d\n", H5Fget_obj_count(file, H5F_OBJ_ATTR));
195     printf("Open all (except the file itself): %d\n", H5Fget_obj_count(file, H5F_OBJ_ALL)  - 1);*/
196
197     //  H5Fflush(file, H5F_SCOPE_GLOBAL);
198     status = H5Fclose(file);
199     if (status < 0)
200     {
201         fprintf(stderr, "%s", "failed to close file");
202     }
203 }
204 /*--------------------------------------------------------------------------*/
205 static char *getPathFilename(char *fullfilename)
206 {
207     char *path = NULL;
208     if (fullfilename)
209     {
210         char* drv  = strdup(fullfilename);
211         char* dir  = strdup(fullfilename);
212         char* name = strdup(fullfilename);
213         char* ext  = strdup(fullfilename);
214
215         path = strdup(fullfilename);
216
217         if (drv && dir && name && ext && path)
218         {
219             splitpath(fullfilename, FALSE, drv, dir, name, ext);
220
221             if (strcmp(drv, "") == 0)
222             {
223                 strcpy(path, dir);
224             }
225             else
226             {
227                 strcpy(path, drv);
228                 strcat(path, dir);
229             }
230         }
231
232         if (drv)
233         {
234             FREE(drv);
235             drv = NULL;
236         }
237         if (dir)
238         {
239             FREE(dir);
240             dir = NULL;
241         }
242         if (name)
243         {
244             FREE(name);
245             name = NULL;
246         }
247         if (ext)
248         {
249             FREE(ext);
250             ext = NULL;
251         }
252     }
253     return path;
254 }
255 /*--------------------------------------------------------------------------*/
256 static char *getFilenameWithExtension(char *fullfilename)
257 {
258     char *filename = NULL;
259     if (fullfilename)
260     {
261         char* drv  = strdup(fullfilename);
262         char* dir  = strdup(fullfilename);
263         char* name = strdup(fullfilename);
264         char* ext  = strdup(fullfilename);
265
266         filename = strdup(fullfilename);
267
268         if (drv && dir && name && ext && filename)
269         {
270             splitpath(fullfilename, FALSE, drv, dir, name, ext);
271
272             if (strcmp(ext, "") == 0)
273             {
274                 strcpy(filename, name);
275             }
276             else
277             {
278                 strcpy(filename, name);
279                 strcat(filename, ext);
280             }
281         }
282
283         if (drv)
284         {
285             FREE(drv);
286             drv = NULL;
287         }
288         if (dir)
289         {
290             FREE(dir);
291             dir = NULL;
292         }
293         if (name)
294         {
295             FREE(name);
296             name = NULL;
297         }
298         if (ext)
299         {
300             FREE(ext);
301             ext = NULL;
302         }
303     }
304     return filename;
305 }
306 /*--------------------------------------------------------------------------*/
307