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