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