f45904487de001eab77cb996d51b451fc649577d
[scilab.git] / scilab / modules / hdf5 / src / c / h5_readDataFromFile.c
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2012 - Scilab Enterprises - Antoine ELIAS
4 *
5 *  This file must be used under the terms of the CeCILL.
6 *  This source file is licensed as described in the file COPYING, which
7 *  you should have received as part of this distribution.  The terms
8 *  are also available at
9 *  http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10 *
11 */
12
13 #define H5_NO_DEPRECATED_SYMBOLS
14
15 #ifndef _MSC_VER
16 #include <sys/time.h>
17 #else
18 #include <windows.h>
19 //#include <winbase.h>
20 #endif
21
22 #include <string.h>
23 #include <hdf5.h>
24 #include <stdlib.h>
25 #include "sci_malloc.h"
26 #include "sci_types.h"
27 #include "h5_attributeConstants.h"
28 #include "h5_readDataFromFile.h"
29 #include "doublecomplex.h"
30
31 //#define TIME_DEBUG
32
33 static herr_t find_attr_by_name(hid_t loc_id, const char *name, const H5A_info_t *ainfo, void *data)
34 {
35     return !strcmp(name, (const char *)data);
36 }
37
38 /************************************************************
39
40 Operator function.  Prints the name and type of the object
41 being examined.
42
43 ************************************************************/
44 static herr_t op_func(hid_t loc_id, const char *name, const H5L_info_t *info, void *operator_data)
45 {
46     H5O_info_t oinfo;
47     herr_t status = 0;
48     int *pDataSetId = (int*)operator_data;
49     hid_t obj = H5Oopen(loc_id, name, H5P_DEFAULT);
50     if (obj < 0)
51     {
52         return -1;
53     }
54
55     /*
56      * Get type of the object and return only datasetId
57      * through operator_data.
58      */
59     status = H5Oget_info(obj, &oinfo);
60     if (status < 0)
61     {
62         H5Oclose(obj);
63         return -1;
64     }
65
66     if (oinfo.type == H5O_TYPE_DATASET)
67     {
68         *pDataSetId = obj;
69     }
70     else
71     {
72         H5Oclose(obj);
73     }
74
75     return 0;
76 }
77
78 static int readIntAttribute(int _iDatasetId, const char *_pstName)
79 {
80     hid_t iAttributeId;
81     herr_t status;
82     int iVal = -1;
83     hsize_t n = 0;
84
85     if (H5Aiterate(_iDatasetId, H5_INDEX_NAME, H5_ITER_NATIVE, &n, find_attr_by_name, (void *)_pstName) > 0)
86     {
87         iAttributeId = H5Aopen(_iDatasetId, _pstName, H5P_DEFAULT);
88         if (iAttributeId < 0)
89         {
90             return -1;
91         }
92
93         status = H5Aread(iAttributeId, H5T_NATIVE_INT, &iVal);
94         if (status < 0)
95         {
96             return -1;
97         }
98
99         status = H5Aclose(iAttributeId);
100         if (status < 0)
101         {
102             return -1;
103         }
104     }
105     return iVal;
106 }
107
108 /*
109 ** WARNING : this function returns an allocated value that must be freed.
110 */
111 static char* readAttribute(int _iDatasetId, const char *_pstName)
112 {
113     hid_t iAttributeId;
114     hid_t iFileType, memtype, iSpace;
115     herr_t status;
116     hsize_t dims[1];
117     size_t iDim;
118     hsize_t n = 0;
119
120     char *pstValue = NULL;
121
122     if (H5Aiterate(_iDatasetId, H5_INDEX_NAME, H5_ITER_NATIVE, &n, find_attr_by_name, (void *)_pstName) > 0)
123     {
124         iAttributeId = H5Aopen(_iDatasetId, _pstName, H5P_DEFAULT);
125         if (iAttributeId < 0)
126         {
127             return NULL;
128         }
129         /*
130          * Get the datatype and its size.
131          */
132         iFileType = H5Aget_type(iAttributeId);
133         iDim = H5Tget_size(iFileType);
134         iDim++;                 /* Make room for null terminator */
135
136         /*
137          * Get dataspace and allocate memory for read buffer.  This is a
138          * two dimensional attribute so the dynamic allocation must be done
139          * in steps.
140          */
141         iSpace = H5Aget_space(iAttributeId);
142         if (iSpace < 0)
143         {
144             return NULL;
145         }
146
147         status = H5Sget_simple_extent_dims(iSpace, dims, NULL);
148         if (status < 0)
149         {
150             return NULL;
151         }
152
153         /*
154          * Allocate space for string data.
155          */
156         pstValue = (char *)MALLOC((size_t) ((dims[0] * iDim + 1) * sizeof(char)));
157
158         /*
159          * Create the memory datatype.
160          */
161         memtype = H5Tcopy(H5T_C_S1);
162         status = H5Tset_size(memtype, iDim);
163         if (status < 0)
164         {
165             FREE(pstValue);
166             return NULL;
167         }
168
169         /*
170          * Read the data.
171          */
172         status = H5Aread(iAttributeId, memtype, pstValue);
173         if (status < 0)
174         {
175             FREE(pstValue);
176             return NULL;
177         }
178
179         status = H5Tclose(memtype);
180         if (status < 0)
181         {
182             FREE(pstValue);
183             return NULL;
184         }
185
186         status = H5Sclose(iSpace);
187         if (status < 0)
188         {
189             FREE(pstValue);
190             return NULL;
191         }
192
193         status = H5Tclose(iFileType);
194         if (status < 0)
195         {
196             FREE(pstValue);
197             return NULL;
198         }
199
200         status = H5Aclose(iAttributeId);
201         if (status < 0)
202         {
203             FREE(pstValue);
204             return NULL;
205         }
206     }
207     return pstValue;
208
209 }
210
211 static int checkAttribute(int _iDatasetId, char *_pstAttribute, char *_pstValue)
212 {
213     int iRet = 0;
214     char *pstScilabClass = NULL;
215
216     //status = H5Giterate (_iFile, "/", NULL, op_func, &iDatasetId);
217     pstScilabClass = readAttribute(_iDatasetId, _pstAttribute);
218     if (pstScilabClass != NULL && strcmp(pstScilabClass, _pstValue) == 0)
219     {
220         iRet = 1;
221     }
222     if (pstScilabClass)
223     {
224         FREE(pstScilabClass);
225     }
226     return iRet;
227 }
228
229 /*
230 ** WARNING : this function returns an allocated value that must be freed.
231 */
232 char* getScilabVersionAttribute(int _iFile)
233 {
234     return readAttribute(_iFile, g_SCILAB_CLASS_SCI_VERSION);
235 }
236
237 int getSODFormatAttribute(int _iFile)
238 {
239     return readIntAttribute(_iFile, g_SCILAB_CLASS_SOD_VERSION);
240 }
241
242 int getDatasetInfo(int _iDatasetId, int* _iComplex, int* _iDims, int* _piDims)
243 {
244     int iSize = 1;
245     hid_t data_type;
246     H5T_class_t data_class;
247     hid_t space = H5Dget_space(_iDatasetId);
248     if (space < 0)
249     {
250         return -1;
251     }
252
253     data_type = H5Dget_type(_iDatasetId);
254     data_class = H5Tget_class(data_type);
255     if (data_class == H5T_COMPOUND)
256     {
257         *_iComplex = 1;
258     }
259     else if (data_class == H5T_REFERENCE)
260     {
261         *_iComplex = isComplexData(_iDatasetId);
262     }
263     else
264     {
265         *_iComplex = 0;
266     }
267
268     *_iDims = H5Sget_simple_extent_ndims(space);
269     if (*_iDims < 0)
270     {
271         H5Sclose(space);
272         return -1;
273     }
274
275     if (_piDims != 0 && *_iDims != 0)
276     {
277         int i = 0;
278         hsize_t* dims = (hsize_t*)MALLOC(sizeof(hsize_t) * *_iDims);
279         if (H5Sget_simple_extent_dims(space, dims, NULL) < 0)
280         {
281             FREE(dims);
282             return -1;
283         }
284
285         //reverse dimensions
286         for (i = 0 ; i < *_iDims ; i++)
287         {
288             //reverse dimensions to improve rendering in external tools
289             _piDims[i] = (int)dims[*_iDims - 1 - i];
290             iSize *= _piDims[i];
291         }
292
293         FREE(dims);
294     }
295     else
296     {
297         iSize = 0;
298     }
299
300     H5Sclose(space);
301     return iSize;
302 }
303
304 int getSparseDimension(int _iDatasetId, int *_piRows, int *_piCols, int *_piNbItem)
305 {
306     int iRet = 0;
307     int iDummy = 0;
308
309     //get number of item in the sparse matrix
310     getDatasetDims(_iDatasetId, _piRows, _piCols);
311     *_piNbItem = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ITEMS);
312
313     return iRet;
314 }
315
316 static int isEmptyDataset(int _iDatasetId)
317 {
318     return checkAttribute(_iDatasetId, (char *)g_SCILAB_CLASS_EMPTY, "true");
319 }
320
321 int isComplexData(int _iDatasetId)
322 {
323     return checkAttribute(_iDatasetId, (char *)g_SCILAB_CLASS_COMPLEX, "true");
324 }
325
326 int getDatasetPrecision(int _iDatasetId, int *_piPrec)
327 {
328     int iRet = 0;
329     char *pstScilabClass = readAttribute(_iDatasetId, g_SCILAB_CLASS_PREC);
330
331     if (pstScilabClass == NULL)
332     {
333         return -1;
334     }
335     else if (strcmp(pstScilabClass, "8") == 0)
336     {
337         *_piPrec = SCI_INT8;
338     }
339     else if (strcmp(pstScilabClass, "u8") == 0)
340     {
341         *_piPrec = SCI_UINT8;
342     }
343     else if (strcmp(pstScilabClass, "16") == 0)
344     {
345         *_piPrec = SCI_INT16;
346     }
347     else if (strcmp(pstScilabClass, "u16") == 0)
348     {
349         *_piPrec = SCI_UINT16;
350     }
351     else if (strcmp(pstScilabClass, "32") == 0)
352     {
353         *_piPrec = SCI_INT32;
354     }
355     else if (strcmp(pstScilabClass, "u32") == 0)
356     {
357         *_piPrec = SCI_UINT32;
358     }
359     else if (strcmp(pstScilabClass, "64") == 0)
360     {
361         *_piPrec = SCI_INT64;
362     }
363     else if (strcmp(pstScilabClass, "u64") == 0)
364     {
365         *_piPrec = SCI_UINT64;
366     }
367     else
368     {
369         iRet = 1;
370     }
371
372     FREE(pstScilabClass);
373     return iRet;
374 }
375
376 int getVariableNames(int _iFile, char **pstNameList)
377 {
378     hsize_t i = 0;
379     hsize_t iCount = 0;
380     herr_t status = 0;
381     int iNbItem = 0;
382     H5O_info_t oinfo;
383     H5G_info_t ginfo;
384
385     status = H5Gget_info(_iFile, &ginfo);
386     if (status != 0)
387     {
388         return 0;
389     }
390
391     iCount = ginfo.nlinks;
392     for (i = 0; i < iCount; i++)
393     {
394         status = H5Oget_info_by_idx(_iFile, "/", H5_INDEX_NAME, H5_ITER_NATIVE, i, &oinfo, H5P_DEFAULT);
395         if (status < 0)
396         {
397             return 0;
398         }
399
400         if (oinfo.type == H5O_TYPE_DATASET)
401         {
402             if (pstNameList != NULL)
403             {
404                 ssize_t iLen = H5Lget_name_by_idx(_iFile, ".", H5_INDEX_NAME, H5_ITER_INC, i, 0, 0, H5P_DEFAULT) + 1;
405                 pstNameList[iNbItem] = (char*)MALLOC(sizeof(char) * iLen);
406                 H5Lget_name_by_idx(_iFile, ".", H5_INDEX_NAME, H5_ITER_INC, i, pstNameList[iNbItem], iLen, H5P_DEFAULT);
407             }
408             iNbItem++;
409         }
410     }
411     return iNbItem;
412 }
413
414 int getDataSetIdFromName(int _iFile, const char *_pstName)
415 {
416     H5O_info_t info;
417     htri_t ret = H5Lexists(_iFile, _pstName, H5P_DEFAULT);
418     if (ret == 1)
419     {
420         H5Oget_info_by_name(_iFile, _pstName, &info, H5P_DEFAULT);
421         if (info.type == H5O_TYPE_GROUP)
422         {
423             return H5Gopen(_iFile, _pstName, H5P_DEFAULT);
424         }
425
426         return H5Dopen(_iFile, _pstName, H5P_DEFAULT);
427     }
428
429     return -1;
430 }
431
432 void closeDataSet(int _id)
433 {
434     if (_id > 0)
435     {
436         herr_t status = H5Dclose(_id);
437         if (status < 0)
438         {
439             return;
440         }
441     }
442
443     return;
444 }
445
446 int getDataSetId(int _iFile)
447 {
448     herr_t status = 0;
449     int iDatasetId = 0;
450     hsize_t idx = 0;
451
452     /*
453      * Begin iteration.
454      */
455     status = H5Literate(_iFile, H5_INDEX_NAME, H5_ITER_NATIVE, &idx, op_func, &iDatasetId);
456     if (status < 0)
457     {
458         return -1;
459     }
460
461     return iDatasetId;
462 }
463
464 int getListDims(int _iDatasetId, int *_piItems)
465 {
466     /*
467      * Get dataspace and dimensions of the dataset. This is a
468      * two dimensional dataset.
469      */
470     if (isEmptyDataset(_iDatasetId))
471     {
472         *_piItems = 0;
473     }
474     else
475     {
476         *_piItems = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ITEMS);
477     }
478     return 0;
479 }
480
481 int getDatasetDims(int _iDatasetId, int *_piRows, int *_piCols)
482 {
483     /*
484      * Get dataspace and dimensions of the dataset. This is a
485      * two dimensional dataset.
486      */
487     if (isEmptyDataset(_iDatasetId))
488     {
489         *_piCols = 0;
490         *_piRows = 0;
491     }
492     else
493     {
494         *_piRows = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ROWS);
495         *_piCols = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_COLS);
496     }
497     return 0;
498 }
499
500 int readDoubleMatrix(int _iDatasetId, double *_pdblData)
501 {
502     herr_t status;
503
504     //Read the data.
505     status = H5Dread(_iDatasetId, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pdblData);
506     if (status < 0)
507     {
508         return -1;
509     }
510
511     status = H5Dclose(_iDatasetId);
512     if (status < 0)
513     {
514         return -1;
515     }
516
517     return 0;
518 }
519
520 int readDoubleComplexMatrix(int _iDatasetId, double *_pdblReal, double *_pdblImg)
521 {
522     hid_t compoundId;
523     herr_t status;
524     int iDims = 0;
525     int* piDims = NULL;
526     int iComplex = 0;
527     int iSize = 1;
528     doublecomplex* pData = NULL;
529     int i = 0;
530
531     /*define compound dataset*/
532     compoundId = H5Tcreate(H5T_COMPOUND, sizeof(doublecomplex));
533     H5Tinsert(compoundId, "real", HOFFSET(doublecomplex, r), H5T_NATIVE_DOUBLE);
534     H5Tinsert(compoundId, "imag", HOFFSET(doublecomplex, i), H5T_NATIVE_DOUBLE);
535
536     //get dimension from dataset
537     getDatasetInfo(_iDatasetId, &iComplex, &iDims, NULL);
538     piDims = (int*)MALLOC(sizeof(int) * iDims);
539     iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, piDims);
540
541     FREE(piDims);
542     //alloc temp array
543     pData = (doublecomplex*)MALLOC(sizeof(doublecomplex) * iSize);
544     //Read the data.
545     status = H5Dread(_iDatasetId, compoundId, H5S_ALL, H5S_ALL, H5P_DEFAULT, pData);
546     if (status < 0)
547     {
548         FREE(pData);
549         return -1;
550     }
551
552
553     vGetPointerFromDoubleComplex(pData, iSize, _pdblReal, _pdblImg);
554     FREE(pData);
555     status = H5Dclose(_iDatasetId);
556     if (status < 0)
557     {
558         return -1;
559     }
560
561     return 0;
562 }
563
564 int readEmptyMatrix(int _iDatasetId)
565 {
566     //close dataset
567     herr_t status;
568
569     status = H5Dclose(_iDatasetId);
570     if (status < 0)
571     {
572         return -1;
573     }
574
575     return 0;
576 }
577
578 int readBooleanMatrix(int _iDatasetId, int *_piData)
579 {
580     herr_t status = 0;
581
582     /*
583      * Read the data.
584      */
585     status = H5Dread(_iDatasetId, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, _piData);
586     if (status < 0)
587     {
588         return -1;
589     }
590
591     status = H5Dclose(_iDatasetId);
592     if (status < 0)
593     {
594         return -1;
595     }
596
597     return 0;
598 }
599
600 int readStringMatrix(int _iDatasetId, char **_pstData)
601 {
602     herr_t status;
603     hid_t typeId;
604
605     typeId = H5Tcopy(H5T_C_S1);
606     status = H5Tset_size(typeId, H5T_VARIABLE);
607     if (status < 0)
608     {
609         return -1;
610     }
611
612     //Read the data.
613     status = H5Dread(_iDatasetId, typeId, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pstData);
614     if (status < 0)
615     {
616         return -1;
617     }
618
619     status = H5Tclose(typeId);
620     if (status < 0)
621     {
622         return -1;
623     }
624
625     return 0;
626 }
627
628 int freeStringMatrix(int _iDatasetId, char** _pstData)
629 {
630     herr_t status;
631     hid_t typeId;
632     hid_t space;
633
634     if (_iDatasetId == -1)
635     {
636         return 0;
637     }
638
639     typeId = H5Tcopy(H5T_C_S1);
640     status = H5Tset_size(typeId, H5T_VARIABLE);
641     if (status < 0)
642     {
643         return -1;
644     }
645
646     space = H5Dget_space (_iDatasetId);
647     status = H5Dvlen_reclaim (typeId, space, H5P_DEFAULT, _pstData);
648     if (status < 0)
649     {
650         return -1;
651     }
652
653     status = H5Sclose(space);
654     if (status < 0)
655     {
656         return -1;
657     }
658
659     status = H5Tclose(typeId);
660     if (status < 0)
661     {
662         return -1;
663     }
664
665     status = H5Dclose(_iDatasetId);
666     if (status < 0)
667     {
668         return -1;
669     }
670
671     return 0;
672 }
673
674 static int readComplexPoly(int _iDatasetId, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
675 {
676     int iComplex = 0;
677     int iSize = 0;
678     int iDims = 0;
679     //Get the datatype and its size.
680
681     iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, _piNbCoef);
682
683     //Allocate space for string data.
684     *_pdblReal = (double *)MALLOC(*_piNbCoef * sizeof(double));
685     *_pdblImg = (double *)MALLOC(*_piNbCoef * sizeof(double));
686
687     //Read the data and return result.
688     return readDoubleComplexMatrix(_iDatasetId, *_pdblReal, *_pdblImg);
689 }
690
691 static int readPoly(int _iDatasetId, int *_piNbCoef, double **_pdblData)
692 {
693     int iComplex = 0;
694     int iSize = 0;
695     int iDims = 0;
696     //Get the datatype and its size.
697     iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, _piNbCoef);
698
699     *_pdblData = (double *)MALLOC(*_piNbCoef * sizeof(double));
700
701     //Read the data and return result.
702     return readDoubleMatrix(_iDatasetId, *_pdblData);
703 }
704
705 int readCommonPolyMatrix(int _iDatasetId, char *_pstVarname, int _iComplex, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
706 {
707     int i = 0;
708     hid_t obj = 0;
709     char *pstVarName = 0;
710     hsize_t* piDims = NULL;
711     hobj_ref_t *pData = NULL;
712     herr_t status;
713     int iSize = 1;
714
715     for (i = 0 ; i < _iDims ; i++)
716     {
717         iSize *= _piDims[i];
718     }
719
720     pData = (hobj_ref_t *) MALLOC(iSize * sizeof(hobj_ref_t));
721
722     /*
723      * Read the data.
724      */
725     status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pData);
726     if (status < 0)
727     {
728         FREE(pData);
729         return -1;
730     }
731
732     for (i = 0; i < iSize; i++)
733     {
734         /*
735          * Open the referenced object, get its name and type.
736          */
737         obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pData[i]);
738         if (_iComplex)
739         {
740             status = readComplexPoly(obj, &_piNbCoef[i], &_pdblReal[i], &_pdblImg[i]);
741         }
742         else
743         {
744             status = readPoly(obj, &_piNbCoef[i], &_pdblReal[i]);
745         }
746
747         if (status < 0)
748         {
749             FREE(pData);
750             return -1;
751         }
752     }
753
754     pstVarName = readAttribute(_iDatasetId, g_SCILAB_CLASS_VARNAME);
755     strcpy(_pstVarname, pstVarName);
756     FREE(pstVarName);
757     status = H5Dclose(_iDatasetId);
758     if (status < 0)
759     {
760         FREE(pData);
761         return -1;
762     }
763
764     FREE(pData);
765
766     return 0;
767 }
768
769 int readPolyMatrix(int _iDatasetId, char *_pstVarname, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblData)
770 {
771     return readCommonPolyMatrix(_iDatasetId, _pstVarname, 0, _iDims, _piDims, _piNbCoef, _pdblData, NULL);
772 }
773
774 int readPolyComplexMatrix(int _iDatasetId, char *_pstVarname, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
775 {
776     return readCommonPolyMatrix(_iDatasetId, _pstVarname, 1, _iDims, _piDims, _piNbCoef, _pdblReal, _pdblImg);
777 }
778
779 int readInteger8Matrix(int _iDatasetId, char *_pcData)
780 {
781     herr_t status = 0;
782
783     /*
784      * Read the data.
785      */
786     status = H5Dread(_iDatasetId, H5T_NATIVE_INT8, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pcData);
787     if (status < 0)
788     {
789         return -1;
790     }
791
792     status = H5Dclose(_iDatasetId);
793     if (status < 0)
794     {
795         return -1;
796     }
797
798     return 0;
799 }
800
801 int readInteger16Matrix(int _iDatasetId, short *_psData)
802 {
803     herr_t status = 0;
804
805     /*
806      * Read the data.
807      */
808     status = H5Dread(_iDatasetId, H5T_NATIVE_INT16, H5S_ALL, H5S_ALL, H5P_DEFAULT, _psData);
809     if (status < 0)
810     {
811         return -1;
812     }
813
814     status = H5Dclose(_iDatasetId);
815     if (status < 0)
816     {
817         return -1;
818     }
819
820     return 0;
821 }
822
823 int readInteger32Matrix(int _iDatasetId, int *_piData)
824 {
825     herr_t status = 0;
826
827     /*
828      * Read the data.
829      */
830     status = H5Dread(_iDatasetId, H5T_NATIVE_INT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, _piData);
831     if (status < 0)
832     {
833         return -1;
834     }
835
836     status = H5Dclose(_iDatasetId);
837     if (status < 0)
838     {
839         return -1;
840     }
841
842     return 0;
843 }
844
845 int readInteger64Matrix(int _iDatasetId, long long *_pllData)
846 {
847     herr_t status = 0;
848
849     /*
850      * Read the data.
851      */
852     status = H5Dread(_iDatasetId, H5T_NATIVE_INT64, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pllData);
853     if (status < 0)
854     {
855         return -1;
856     }
857
858     status = H5Dclose(_iDatasetId);
859     if (status < 0)
860     {
861         return -1;
862     }
863
864     return 0;
865 }
866
867 int readUnsignedInteger8Matrix(int _iDatasetId, unsigned char *_pucData)
868 {
869     herr_t status = 0;
870
871     /*
872      * Read the data.
873      */
874     status = H5Dread(_iDatasetId, H5T_NATIVE_UINT8, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pucData);
875     if (status < 0)
876     {
877         return -1;
878     }
879
880     status = H5Dclose(_iDatasetId);
881     if (status < 0)
882     {
883         return -1;
884     }
885
886     return 0;
887 }
888
889 int readUnsignedInteger16Matrix(int _iDatasetId, unsigned short *_pusData)
890 {
891     herr_t status = 0;
892
893     /*
894      * Read the data.
895      */
896     status = H5Dread(_iDatasetId, H5T_NATIVE_UINT16, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pusData);
897     if (status < 0)
898     {
899         return -1;
900     }
901
902     status = H5Dclose(_iDatasetId);
903     if (status < 0)
904     {
905         return -1;
906     }
907
908     return 0;
909 }
910
911 int readUnsignedInteger32Matrix(int _iDatasetId, unsigned int *_puiData)
912 {
913     herr_t status = 0;
914
915     /*
916      * Read the data.
917      */
918     status = H5Dread(_iDatasetId, H5T_NATIVE_UINT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, _puiData);
919     if (status < 0)
920     {
921         return -1;
922     }
923
924     status = H5Dclose(_iDatasetId);
925     if (status < 0)
926     {
927         return -1;
928     }
929
930     return 0;
931 }
932
933 int readUnsignedInteger64Matrix(int _iDatasetId, unsigned long long *_pullData)
934 {
935     herr_t status = 0;
936
937     /*
938      * Read the data.
939      */
940     status = H5Dread(_iDatasetId, H5T_NATIVE_UINT64, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pullData);
941     if (status < 0)
942     {
943         return -1;
944     }
945
946     status = H5Dclose(_iDatasetId);
947     if (status < 0)
948     {
949         return -1;
950     }
951
952     return 0;
953 }
954
955 int readCommonSparseComplexMatrix(int _iDatasetId, int _iComplex, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal, double *_pdblImg)
956 {
957     hid_t obj = 0;
958     hobj_ref_t pRef[3] = {0};
959     herr_t status;
960
961     /*
962      * Read the data.
963      */
964     status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pRef);
965     if (status < 0)
966     {
967         return -1;
968     }
969
970     //read Row data
971     obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[0]);
972     status = readInteger32Matrix(obj, _piNbItemRow);
973     if (status < 0)
974     {
975         return -1;
976     }
977
978     //read cols data
979     obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[1]);
980     status = readInteger32Matrix(obj, _piColPos);
981     if (status < 0)
982     {
983         return -1;
984     }
985
986     //read sparse data
987     obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[2]);
988
989     if (_iComplex)
990     {
991         status = readDoubleComplexMatrix(obj, _pdblReal, _pdblImg);
992     }
993     else
994     {
995         status = readDoubleMatrix(obj, _pdblReal);
996     }
997
998     if (status < 0)
999     {
1000         return -1;
1001     }
1002
1003     status = H5Dclose(_iDatasetId);
1004     if (status < 0)
1005     {
1006         return -1;
1007     }
1008
1009     return 0;
1010 }
1011
1012 int readSparseMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal)
1013 {
1014     return readCommonSparseComplexMatrix(_iDatasetId, 0, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
1015 }
1016
1017 int readSparseComplexMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal, double *_pdblImg)
1018 {
1019     return readCommonSparseComplexMatrix(_iDatasetId, 1, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
1020 }
1021
1022 int readBooleanSparseMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos)
1023 {
1024     hid_t obj = 0;
1025     hobj_ref_t pRef[2] = {0};
1026     herr_t status;
1027
1028     /*
1029      * Read the data.
1030      */
1031     status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pRef);
1032     if (status < 0)
1033     {
1034         return -1;
1035     }
1036
1037     //read Row data
1038     obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[0]);
1039     status = readInteger32Matrix(obj, _piNbItemRow);
1040     if (status < 0)
1041     {
1042         return -1;
1043     }
1044
1045     if (_iNbItem != 0)
1046     {
1047         //read cols data
1048         obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[1]);
1049         status = readInteger32Matrix(obj, _piColPos);
1050         if (status < 0)
1051         {
1052             return -1;
1053         }
1054     }
1055
1056     status = H5Dclose(_iDatasetId);
1057     if (status < 0)
1058     {
1059         return -1;
1060     }
1061     return 0;
1062 }
1063
1064 int getScilabTypeFromDataSet(int _iDatasetId)
1065 {
1066     int iVarType = 0;
1067     char *pstScilabClass = readAttribute(_iDatasetId, g_SCILAB_CLASS);
1068
1069     if (pstScilabClass == NULL)
1070     {
1071         return unknow_type;
1072     }
1073     /* HDF5 Float type + SCILAB_Class = double <=> double */
1074     if (strcmp(pstScilabClass, g_SCILAB_CLASS_DOUBLE) == 0)
1075     {
1076         iVarType = sci_matrix;
1077     }
1078     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_STRING) == 0)
1079     {
1080         iVarType = sci_strings;
1081     }
1082     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BOOLEAN) == 0)
1083     {
1084         iVarType = sci_boolean;
1085     }
1086     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BOOLEAN) == 0)
1087     {
1088         iVarType = sci_boolean;
1089     }
1090     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_POLY) == 0)
1091     {
1092         iVarType = sci_poly;
1093     }
1094     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_INT) == 0)
1095     {
1096         iVarType = sci_ints;
1097     }
1098     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_SPARSE) == 0)
1099     {
1100         iVarType = sci_sparse;
1101     }
1102     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BSPARSE) == 0)
1103     {
1104         iVarType = sci_boolean_sparse;
1105     }
1106     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_LIST) == 0)
1107     {
1108         iVarType = sci_list;
1109     }
1110     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_TLIST) == 0)
1111     {
1112         iVarType = sci_tlist;
1113     }
1114     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_MLIST) == 0)
1115     {
1116         iVarType = sci_mlist;
1117     }
1118     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_VOID) == 0)
1119     {
1120         iVarType = sci_void;
1121     }
1122     else if (strcmp(pstScilabClass, g_SCILAB_CLASS_UNDEFINED) == 0)
1123     {
1124         iVarType = sci_undefined;
1125     }
1126
1127     FREE(pstScilabClass);
1128     return iVarType;
1129 }
1130
1131 int getListItemReferences(int _iDatasetId, hobj_ref_t ** _piItemRef)
1132 {
1133     int iItem = 0;
1134     herr_t status = 0;
1135
1136     getListDims(_iDatasetId, &iItem);
1137
1138     *_piItemRef = (hobj_ref_t *) MALLOC(iItem * sizeof(hobj_ref_t));
1139
1140     status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, *_piItemRef);
1141     if (status < 0)
1142     {
1143         return -1;
1144     }
1145
1146     return 0;
1147 }
1148
1149 int getListItemDataset(int _iDatasetId, void *_piItemRef, int _iItemPos, int *_piItemDataset)
1150 {
1151     hobj_ref_t poRef = ((hobj_ref_t *) _piItemRef)[_iItemPos];
1152
1153     *_piItemDataset = H5Rdereference(_iDatasetId, H5R_OBJECT, &poRef);
1154
1155     if (*_piItemDataset == 0)
1156     {
1157         return -1;
1158     }
1159
1160     return 0;
1161 }
1162
1163 int deleteListItemReferences(int _iDatasetId, void *_piItemRef)
1164 {
1165     herr_t status;
1166
1167     if (_piItemRef)
1168     {
1169         hobj_ref_t *poRef = (hobj_ref_t *) _piItemRef;
1170
1171         FREE(poRef);
1172     }
1173
1174     status = H5Dclose(_iDatasetId);
1175     if (status < 0)
1176     {
1177         return -1;
1178     }
1179
1180     return 0;
1181 }
1182
1183 //Scilab 6
1184 char* getScilabTypeFromDataSet6(int dataset)
1185 {
1186     return readAttribute(dataset, g_SCILAB_CLASS);
1187 }
1188
1189 int getListDims6(int dataset, int* items)
1190 {
1191     H5G_info_t group_info;
1192     herr_t status = H5Gget_info(dataset, &group_info);
1193     if (status < 0)
1194     {
1195         *items = 0;
1196         return -1;
1197     }
1198
1199     *items = (int)group_info.nlinks;
1200     return 0;
1201 }
1202
1203 int getVariableNames6(int _iFile, char **names)
1204 {
1205     hsize_t i = 0;
1206     hsize_t iCount = 0;
1207     herr_t status = 0;
1208     int iNbItem = 0;
1209     H5O_info_t oinfo;
1210     H5G_info_t ginfo;
1211
1212     status = H5Gget_info(_iFile, &ginfo);
1213     if (status != 0)
1214     {
1215         return 0;
1216     }
1217
1218     iCount = ginfo.nlinks;
1219     for (i = 0; i < iCount; i++)
1220     {
1221         status = H5Oget_info_by_idx(_iFile, ".", H5_INDEX_NAME, H5_ITER_NATIVE, i, &oinfo, H5P_DEFAULT);
1222         if (status < 0)
1223         {
1224             return 0;
1225         }
1226
1227         if (oinfo.type == H5O_TYPE_DATASET || oinfo.type == H5O_TYPE_GROUP)
1228         {
1229             if (names != NULL)
1230             {
1231                 ssize_t iLen = H5Lget_name_by_idx(_iFile, ".", H5_INDEX_NAME, H5_ITER_INC, i, 0, 0, H5P_DEFAULT) + 1;
1232                 names[iNbItem] = (char*)MALLOC(sizeof(char) * iLen);
1233                 H5Lget_name_by_idx(_iFile, ".", H5_INDEX_NAME, H5_ITER_INC, i, names[iNbItem], iLen, H5P_DEFAULT);
1234             }
1235             iNbItem++;
1236         }
1237     }
1238     return iNbItem;
1239 }