6658877255e7a3c40cb991230dec1ba7e8d3a005
[scilab.git] / scilab / modules / hdf5 / src / cpp / listvar_in_hdf5_v1.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - DIGITEO - 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.1-en.txt
10 *
11 */
12
13 #include <hdf5.h>
14 extern "C"
15 {
16 #include <string.h>
17 #include "gw_hdf5.h"
18 #include "MALLOC.h"
19 #include "Scierror.h"
20 #include "localization.h"
21 #include "sciprint.h"
22 #include "api_scilab.h"
23 #include "../../../call_scilab/includes/call_scilab.h"
24 #include "h5_fileManagement.h"
25 #include "h5_readDataFromFile_v1.h"
26 #include "expandPathVariable.h"
27 }
28
29 #include <vector>
30
31 typedef struct __VAR_INFO_V1__
32 {
33     char pstInfo[128];
34     char varName[128];
35     int iType;
36     int iSize;
37     int iDims;
38     int piDims[2];
39
40     __VAR_INFO_V1__() : iType(0), iSize(0), iDims(0) {}
41 } VarInfo_v1;
42
43 static bool read_data_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
44 static bool read_double_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
45 static bool read_string_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
46 static bool read_boolean_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
47 static bool read_integer_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
48 static bool read_sparse_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
49 static bool read_boolean_sparse_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
50 static bool read_poly_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
51 static bool read_list_v1(int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
52 static bool read_void_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
53 static bool read_undefined_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo);
54
55 static void generateInfo_v1(VarInfo_v1* _pInfo, const char* _pstType);
56
57 int sci_listvar_in_hdf5_v1(char *fname, unsigned long fname_len)
58 {
59     SciErr sciErr;
60     int *piAddr     = NULL;
61     char* pstFile   = NULL;
62     int iFile       = 0;
63     int iNbItem     = 0;
64     VarInfo_v1* pInfo  = NULL;
65
66     CheckRhs(1, 1);
67     CheckLhs(1, 4);
68
69     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
70     if (sciErr.iErr)
71     {
72         printError(&sciErr, 0);
73         return 1;
74     }
75
76     if (getAllocatedSingleString(pvApiCtx, piAddr, &pstFile))
77     {
78         Scierror(999, _("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 1);
79         return 1;
80     }
81
82     char* pstFileName = expandPathVariable(pstFile);
83     iFile = openHDF5File(pstFileName, 0);
84     if (iFile < 0)
85     {
86         FREE(pstFileName);
87         Scierror(999, _("%s: Unable to open file: %s\n"), fname, pstFile);
88         FREE(pstFile);
89         return 1;
90     }
91     FREE(pstFileName);
92     FREE(pstFile);
93
94     iNbItem = getVariableNames_v1(iFile, NULL);
95     if (iNbItem != 0)
96     {
97         char** pstVarNameList = (char**)MALLOC(sizeof(char*) * iNbItem);
98         bool b;
99         pInfo = (VarInfo_v1*)MALLOC(iNbItem * sizeof(VarInfo_v1));
100
101         if (Lhs == 1)
102         {
103             sciprint("Name                     Type           Size            Bytes\n");
104             sciprint("---------------------------------------------------------------\n");
105         }
106
107         iNbItem = getVariableNames_v1(iFile, pstVarNameList);
108         for (int i = 0; i < iNbItem; i++)
109         {
110             int iDataSetId = getDataSetIdFromName_v1(iFile, pstVarNameList[i]);
111             if (iDataSetId == 0)
112             {
113                 break;
114             }
115
116             strcpy(pInfo[i].varName, pstVarNameList[i]);
117             FREE(pstVarNameList[i]);
118             b = read_data_v1(iDataSetId, 0, NULL, &pInfo[i]) == false;
119             closeDataSet_v1(iDataSetId);
120
121             if (b)
122             {
123                 break;
124             }
125
126             if (Lhs == 1)
127             {
128                 sciprint("%s\n", pInfo[i].pstInfo);
129             }
130         }
131     }
132     else
133     {
134         //no variable returms [] for each Lhs
135         for (int i = 0 ; i < Lhs ; i++)
136         {
137             createEmptyMatrix(pvApiCtx, Rhs + i + 1);
138             LhsVar(i + 1) = Rhs + i + 1;
139         }
140
141         PutLhsVar();
142         return 0;
143     }
144
145     closeHDF5File(iFile);
146
147     //1st Lhs
148     char** pstVarName = (char**)MALLOC(sizeof(char*) * iNbItem);
149     for (int i = 0 ; i < iNbItem ; i++)
150     {
151         pstVarName[i] = pInfo[i].varName;
152     }
153
154     sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, iNbItem, 1, pstVarName);
155     FREE(pstVarName);
156     if (sciErr.iErr)
157     {
158         printError(&sciErr, 0);
159         return 1;
160     }
161
162     LhsVar(1) = Rhs + 1;
163
164     if (Lhs > 1)
165     {
166         //2nd Lhs
167         double* pdblType;
168         sciErr = allocMatrixOfDouble(pvApiCtx, Rhs + 2, iNbItem, 1, &pdblType);
169         if (sciErr.iErr)
170         {
171             printError(&sciErr, 0);
172             return 1;
173         }
174
175         for (int i = 0 ; i < iNbItem ; i++)
176         {
177             pdblType[i] = pInfo[i].iType;
178         }
179
180         LhsVar(2) = Rhs + 2;
181
182         if (Lhs > 2)
183         {
184             //3rd Lhs
185             int* pList = NULL;
186             sciErr = createList(pvApiCtx, Rhs + 3, iNbItem, &pList);
187             for (int i = 0 ; i < iNbItem ; i++)
188             {
189                 double* pdblDims = NULL;
190                 allocMatrixOfDoubleInList(pvApiCtx, Rhs + 3, pList, i + 1, 1, pInfo[i].iDims, &pdblDims);
191                 for (int j = 0 ; j < pInfo[i].iDims ; j++)
192                 {
193                     pdblDims[j] = pInfo[i].piDims[j];
194                 }
195             }
196
197             LhsVar(3) = Rhs + 3;
198         }
199
200         if (Lhs > 3)
201         {
202             //4th Lhs
203             double* pdblSize;
204             sciErr = allocMatrixOfDouble(pvApiCtx, Rhs + 4, iNbItem, 1, &pdblSize);
205             for (int i = 0 ; i < iNbItem ; i++)
206             {
207                 pdblSize[i] = pInfo[i].iSize;
208             }
209
210             LhsVar(4) = Rhs + 4;
211         }
212
213     }
214
215     FREE(pInfo);
216     PutLhsVar();
217     return 0;
218 }
219
220 static bool read_data_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
221 {
222     bool bRet = false;
223
224     _pInfo->iType = getScilabTypeFromDataSet_v1(_iDatasetId);
225     switch (_pInfo->iType)
226     {
227         case sci_matrix:
228         {
229             bRet = read_double_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
230             break;
231         }
232         case sci_strings:
233         {
234             bRet = read_string_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
235             break;
236         }
237         case sci_list:
238         case sci_tlist:
239         case sci_mlist:
240         {
241             bRet = read_list_v1(_iDatasetId, _pInfo->iType, _iItemPos, _piAddress, _pInfo);
242             break;
243         }
244         case sci_boolean:
245         {
246             bRet = read_boolean_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
247             break;
248         }
249         case sci_poly:
250         {
251             bRet = read_poly_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
252             break;
253         }
254         case sci_ints:
255         {
256             bRet = read_integer_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
257             break;
258         }
259         case sci_sparse:
260         {
261             bRet = read_sparse_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
262             break;
263         }
264         case sci_boolean_sparse:
265         {
266             bRet = read_boolean_sparse_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
267             break;
268         }
269         case sci_void:             //void item only on list variable
270         {
271             bRet = read_void_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
272             break;
273         }
274         case sci_undefined:        //undefined item only on list variable
275         {
276             bRet = read_undefined_v1(_iDatasetId, _iItemPos, _piAddress, _pInfo);
277             break;
278         }
279         default:
280         {
281             Scierror(999, _("%s: Invalid HDF5 Scilab format.\n"), "listvar_in_hdf5");
282             break;
283         }
284     }
285
286     return bRet;
287 }
288
289 static bool read_double_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
290 {
291     int iRet = 0;
292     int iRows = 0;
293     int iCols = 0;
294     int iComplex = 0;
295
296     iRet = getDatasetDims_v1(_iDatasetId, &iRows, &iCols);
297     iComplex = isComplexData_v1(_iDatasetId);
298
299     _pInfo->iDims = 2;
300     _pInfo->piDims[0] = iRows;
301     _pInfo->piDims[1] = iCols;
302     _pInfo->iSize = (2 + (iRows * iCols * (iComplex + 1))) * 8;
303
304     generateInfo_v1(_pInfo, "constant");
305     return true;
306 }
307
308 static bool read_string_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
309 {
310     int iRet = 0;
311     int iRows = 0;
312     int iCols = 0;
313     char** pstData = NULL;
314
315     iRet = getDatasetDims_v1(_iDatasetId, &iRows, &iCols);
316
317     _pInfo->iDims = 2;
318     _pInfo->piDims[0] = iRows;
319     _pInfo->piDims[1] = iCols;
320
321     pstData = (char **)MALLOC(iRows * iCols * sizeof(char *));
322     iRet = readStringMatrix_v1(_iDatasetId, iRows, iCols, pstData);
323
324
325     for (int i = 0 ; i < iRows * iCols ; i++)
326     {
327         _pInfo->iSize += (int)strlen(pstData[i]) * 4;
328         FREE(pstData[i]);
329     }
330
331     FREE(pstData);
332     //always full double size
333     _pInfo->iSize += (8 - (_pInfo->iSize % 8));
334     //header + offset
335     _pInfo->iSize += 16 + (1 + iRows * iCols) * 4;
336
337     generateInfo_v1(_pInfo, "string");
338     return true;
339 }
340
341 static bool read_boolean_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
342 {
343     int iRet = 0;
344     int iRows = 0;
345     int iCols = 0;
346
347     iRet = getDatasetDims_v1(_iDatasetId, &iRows, &iCols);
348
349     _pInfo->iDims = 2;
350     _pInfo->piDims[0] = iRows;
351     _pInfo->piDims[1] = iCols;
352     _pInfo->iSize = (3 + iRows * iCols) * 4;
353
354     generateInfo_v1(_pInfo, "boolean");
355     return true;
356 }
357
358 static bool read_integer_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
359 {
360     int iRet = 0;
361     int iRows = 0;
362     int iCols = 0;
363     int iPrec = 0;
364
365     iRet = getDatasetDims_v1(_iDatasetId, &iRows, &iCols);
366     iRet = getDatasetPrecision_v1(_iDatasetId, &iPrec);
367
368     _pInfo->iDims = 2;
369     _pInfo->piDims[0] = iRows;
370     _pInfo->piDims[1] = iCols;
371     _pInfo->iSize = 16 + iRows * iCols * (iPrec % 10);
372
373     generateInfo_v1(_pInfo, "integer");
374     return true;
375 }
376
377 static bool read_sparse_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
378 {
379     int iRet = 0;
380     int iRows = 0;
381     int iCols = 0;
382     int iNbItem = 0;
383     int iComplex = 0;
384
385     iRet = getSparseDimension_v1(_iDatasetId, &iRows, &iCols, &iNbItem);
386     if (iRet)
387     {
388         return false;
389     }
390
391     iComplex = isComplexData_v1(_iDatasetId);
392
393     _pInfo->iDims = 2;
394     _pInfo->piDims[0] = iRows;
395     _pInfo->piDims[1] = iCols;
396     _pInfo->iSize = 20 + iRows * 4 + iNbItem * 4 + (iNbItem * (iComplex + 1) * 8);
397
398     generateInfo_v1(_pInfo, "sparse");
399     return true;
400 }
401
402 static bool read_boolean_sparse_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
403 {
404     int iRet = 0;
405     int iRows = 0;
406     int iCols = 0;
407     int iNbItem = 0;
408     int iComplex = 0;
409
410     iRet = getSparseDimension_v1(_iDatasetId, &iRows, &iCols, &iNbItem);
411     if (iRet)
412     {
413         return false;
414     }
415
416     _pInfo->iDims = 2;
417     _pInfo->piDims[0] = iRows;
418     _pInfo->piDims[1] = iCols;
419     _pInfo->iSize = 20 + iRows * 4 + iNbItem * 4;
420
421     generateInfo_v1(_pInfo, "boolean sparse");
422     return true;
423 }
424
425 static bool read_poly_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
426 {
427     int iRet = 0;
428     int iRows = 0;
429     int iCols = 0;
430     int iComplex = 0;
431     char pstVarName[64] = { 0 };
432     double **pdblReal = NULL;
433     double **pdblImg = NULL;
434     int *piNbCoef = NULL;
435
436     iRet = getDatasetDims_v1(_iDatasetId, &iRows, &iCols);
437     if (iRet)
438     {
439         return false;
440     }
441
442     iComplex = isComplexData_v1(_iDatasetId);
443
444     _pInfo->iDims = 2;
445     _pInfo->piDims[0] = iRows;
446     _pInfo->piDims[1] = iCols;
447     _pInfo->iSize = 8 * 4 + (iRows * iCols + 1) * 4;
448
449     if (iComplex)
450     {
451         piNbCoef = (int *)MALLOC(iRows * iCols * sizeof(int));
452         pdblReal = (double **)MALLOC(iRows * iCols * sizeof(double *));
453         pdblImg = (double **)MALLOC(iRows * iCols * sizeof(double *));
454         iRet = readPolyComplexMatrix_v1(_iDatasetId, pstVarName, iRows, iCols, piNbCoef, pdblReal, pdblImg);
455     }
456     else
457     {
458         piNbCoef = (int *)MALLOC(iRows * iCols * sizeof(int));
459         pdblReal = (double **)MALLOC(iRows * iCols * sizeof(double *));
460         iRet = readPolyMatrix_v1(_iDatasetId, pstVarName, iRows, iCols, piNbCoef, pdblReal);
461     }
462
463     for (int i = 0 ; i < iRows * iCols ; i++)
464     {
465         _pInfo->iSize += piNbCoef[i] * 8 * (iComplex + 1);
466         FREE(pdblReal[i]);
467         if (iComplex)
468         {
469             FREE(pdblImg[i]);
470         }
471     }
472
473     FREE(piNbCoef);
474     FREE(pdblReal);
475     if (iComplex)
476     {
477         FREE(pdblImg);
478     }
479
480     generateInfo_v1(_pInfo, "polynomial");
481     return true;
482 }
483
484 static bool read_list_v1(int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
485 {
486     int iRet = 0;
487     int iItems = 0;
488     int *piListAddr = NULL;
489     hobj_ref_t *piItemRef = NULL;
490
491     iRet = getListDims_v1(_iDatasetId, &iItems);
492     if (iRet)
493     {
494         return false;
495     }
496
497     if (iItems == 0)
498     {
499         //special case for empty list
500     }
501     else
502     {
503         iRet = getListItemReferences_v1(_iDatasetId, &piItemRef);
504         if (iRet)
505         {
506             return false;
507         }
508     }
509     //_pInfo = (VarInfo_v1*)MALLOC(sizeof(VarInfo));
510     _pInfo->iDims = 1;
511     _pInfo->piDims[0] = iItems;
512     _pInfo->iSize = (2 + iItems + 1) * 4;
513
514     for (int i = 0; i < iItems; i++)
515     {
516         int iItemDataset = 0;
517
518         iRet = getListItemDataset_v1(_iDatasetId, piItemRef, i, &iItemDataset);
519         if (iRet || iItemDataset == 0)
520         {
521             return false;
522         }
523         VarInfo_v1 info;
524         bool bRet = read_data_v1(iItemDataset, i + 1, piListAddr, &info);
525         if (bRet == false)
526         {
527             return false;
528         }
529
530         _pInfo->iSize += info.iSize;
531     }
532
533     if (_iVarType == sci_list)
534     {
535         generateInfo_v1(_pInfo, "list");
536     }
537     else if (_iVarType == sci_tlist)
538     {
539         generateInfo_v1(_pInfo, "tlist");
540     }
541     else if (_iVarType == sci_mlist)
542     {
543         generateInfo_v1(_pInfo, "mlist");
544     }
545
546     return true;
547 }
548
549 static bool read_void_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
550 {
551     _pInfo->iSize = 1;
552     return true;
553 }
554
555 static bool read_undefined_v1(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo_v1* _pInfo)
556 {
557     _pInfo->iSize = 1;
558     return true;
559 }
560
561 static void generateInfo_v1(VarInfo_v1* _pInfo, const char* _pstType)
562 {
563     char pstSize[17];
564
565     if (_pInfo->iDims == 2)
566     {
567         sprintf(pstSize, "%d by %d", _pInfo->piDims[0], _pInfo->piDims[1]);
568     }
569     else
570     {
571         sprintf(pstSize, "%d", _pInfo->piDims[0]);
572     }
573     sprintf(_pInfo->pstInfo, "%-*s%-*s%-*s%-*d", 25, _pInfo->varName, 15, _pstType, 16, pstSize, 10, _pInfo->iSize);
574 }
575