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