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