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