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