2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - DIGITEO - Antoine ELIAS
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
20 #include "localization.h"
22 #include "api_scilab.h"
23 #include "../../../call_scilab/includes/call_scilab.h"
24 #include "h5_fileManagement.h"
25 #include "h5_readDataFromFile.h"
26 #include "h5_attributeConstants.h"
27 #include "expandPathVariable.h"
30 #include "listvar_in_hdf5_v1.hxx"
33 typedef struct __VAR_INFO__
42 __VAR_INFO__() : iType(0), iSize(0), iDims(0) {}
45 static bool read_data(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
46 static bool read_double(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
47 static bool read_string(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
48 static bool read_boolean(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
49 static bool read_integer(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
50 static bool read_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
51 static bool read_boolean_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
52 static bool read_poly(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
53 static bool read_list(int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
54 static bool read_void(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
55 static bool read_undefined(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
57 static void generateInfo(VarInfo* _pInfo, const char* _pstType);
59 int sci_listvar_in_hdf5(char *fname, unsigned long fname_len)
66 VarInfo* pInfo = NULL;
71 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
74 printError(&sciErr, 0);
78 if (getAllocatedSingleString(pvApiCtx, piAddr, &pstFile))
80 Scierror(999, _("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 1);
84 char* pstFileName = expandPathVariable(pstFile);
85 iFile = openHDF5File(pstFileName, 0);
88 Scierror(999, _("%s: Unable to open file: %s\n"), fname, pstFile);
97 //manage version information
98 int iVersion = getSODFormatAttribute(iFile);
99 if (iVersion != SOD_FILE_VERSION)
101 if (iVersion > SOD_FILE_VERSION)
103 //can't read file with version newer that me !
104 closeHDF5File(iFile);
105 Scierror(999, _("%s: Wrong SOD file format version. Max Expected: %d Found: %d\n"), fname, SOD_FILE_VERSION, iVersion);
110 //call older import functions and exit or ... EXIT !
111 if (iVersion == 1 || iVersion == -1)
113 //sciprint("old sci_listvar_in_hdf5_v1\n");
114 return sci_listvar_in_hdf5_v1(fname, fname_len);
119 iNbItem = getVariableNames(iFile, NULL);
122 char** pstVarNameList = (char**)MALLOC(sizeof(char*) * iNbItem);
123 pInfo = (VarInfo*)MALLOC(iNbItem * sizeof(VarInfo));
128 sciprint("Name Type Size Bytes\n");
129 sciprint("---------------------------------------------------------------\n");
132 iNbItem = getVariableNames(iFile, pstVarNameList);
133 for (int i = 0; i < iNbItem; i++)
135 int iDataSetId = getDataSetIdFromName(iFile, pstVarNameList[i]);
141 strcpy(pInfo[i].varName, pstVarNameList[i]);
142 FREE(pstVarNameList[i]);
143 b = read_data(iDataSetId, 0, NULL, &pInfo[i]) == false;
151 sciprint("%s\n", pInfo[i].pstInfo);
157 //no variable returms [] for each Lhs
158 for (int i = 0 ; i < Lhs ; i++)
160 createEmptyMatrix(pvApiCtx, Rhs + i + 1);
161 LhsVar(i + 1) = Rhs + i + 1;
168 closeHDF5File(iFile);
171 char** pstVarName = (char**)MALLOC(sizeof(char*) * iNbItem);
172 for (int i = 0 ; i < iNbItem ; i++)
174 pstVarName[i] = pInfo[i].varName;
177 sciErr = createMatrixOfString(pvApiCtx, Rhs + 1, iNbItem, 1, pstVarName);
181 printError(&sciErr, 0);
191 sciErr = allocMatrixOfDouble(pvApiCtx, Rhs + 2, iNbItem, 1, &pdblType);
194 printError(&sciErr, 0);
198 for (int i = 0 ; i < iNbItem ; i++)
200 pdblType[i] = pInfo[i].iType;
209 sciErr = createList(pvApiCtx, Rhs + 3, iNbItem, &pList);
210 for (int i = 0 ; i < iNbItem ; i++)
212 double* pdblDims = NULL;
213 allocMatrixOfDoubleInList(pvApiCtx, Rhs + 3, pList, i + 1, 1, pInfo[i].iDims, &pdblDims);
214 for (int j = 0 ; j < pInfo[i].iDims ; j++)
216 pdblDims[j] = pInfo[i].piDims[j];
227 sciErr = allocMatrixOfDouble(pvApiCtx, Rhs + 4, iNbItem, 1, &pdblSize);
228 for (int i = 0 ; i < iNbItem ; i++)
230 pdblSize[i] = pInfo[i].iSize;
243 static bool read_data(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
247 _pInfo->iType = getScilabTypeFromDataSet(_iDatasetId);
248 switch (_pInfo->iType)
252 bRet = read_double(_iDatasetId, _iItemPos, _piAddress, _pInfo);
257 bRet = read_string(_iDatasetId, _iItemPos, _piAddress, _pInfo);
264 bRet = read_list(_iDatasetId, _pInfo->iType, _iItemPos, _piAddress, _pInfo);
269 bRet = read_boolean(_iDatasetId, _iItemPos, _piAddress, _pInfo);
274 bRet = read_poly(_iDatasetId, _iItemPos, _piAddress, _pInfo);
279 bRet = read_integer(_iDatasetId, _iItemPos, _piAddress, _pInfo);
284 bRet = read_sparse(_iDatasetId, _iItemPos, _piAddress, _pInfo);
287 case sci_boolean_sparse:
289 bRet = read_boolean_sparse(_iDatasetId, _iItemPos, _piAddress, _pInfo);
292 case sci_void: //void item only on list variable
294 bRet = read_void(_iDatasetId, _iItemPos, _piAddress, _pInfo);
297 case sci_undefined: //undefined item only on list variable
299 bRet = read_undefined(_iDatasetId, _iItemPos, _piAddress, _pInfo);
304 Scierror(999, _("%s: Invalid HDF5 Scilab format.\n"), "listvar_in_hdf5");
312 static bool read_double(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
317 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
318 _pInfo->iSize = (2 + (iSize * (iComplex + 1))) * 8;
320 generateInfo(_pInfo, "constant");
321 closeDataSet(_iDatasetId);
325 static bool read_string(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
330 char** pstData = NULL;
332 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
334 pstData = (char **)MALLOC(iSize * sizeof(char *));
335 iRet = readStringMatrix(_iDatasetId, pstData);
338 for (int i = 0 ; i < _pInfo->piDims[0] * _pInfo->piDims[1] ; i++)
340 _pInfo->iSize += (int)strlen(pstData[i]) * 4;
344 //always full double size
345 _pInfo->iSize += (8 - (_pInfo->iSize % 8));
347 _pInfo->iSize += 16 + (1 + iSize) * 4;
349 generateInfo(_pInfo, "string");
353 static bool read_boolean(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
358 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
359 _pInfo->iSize = (3 + iSize) * 4;
361 generateInfo(_pInfo, "boolean");
362 closeDataSet(_iDatasetId);
366 static bool read_integer(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
373 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
374 getDatasetPrecision(_iDatasetId, &iPrec);
376 _pInfo->iSize = 16 + iSize * (iPrec % 10);
378 generateInfo(_pInfo, "integer");
379 closeDataSet(_iDatasetId);
383 static bool read_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
391 iRet = getSparseDimension(_iDatasetId, &iRows, &iCols, &iNbItem);
397 iComplex = isComplexData(_iDatasetId);
400 _pInfo->piDims[0] = iRows;
401 _pInfo->piDims[1] = iCols;
402 _pInfo->iSize = 20 + iRows * 4 + iNbItem * 4 + (iNbItem * (iComplex + 1) * 8);
404 generateInfo(_pInfo, "sparse");
405 closeDataSet(_iDatasetId);
409 static bool read_boolean_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
417 iRet = getSparseDimension(_iDatasetId, &iRows, &iCols, &iNbItem);
424 _pInfo->piDims[0] = iRows;
425 _pInfo->piDims[1] = iCols;
426 _pInfo->iSize = 20 + iRows * 4 + iNbItem * 4;
428 generateInfo(_pInfo, "boolean sparse");
429 closeDataSet(_iDatasetId);
433 static bool read_poly(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
437 char pstVarName[64] = { 0 };
438 double **pdblReal = NULL;
439 double **pdblImg = NULL;
440 int *piNbCoef = NULL;
443 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
444 _pInfo->iSize = 8 * 4 + (iSize + 1) * 4;
448 piNbCoef = (int *)MALLOC(iSize * sizeof(int));
449 pdblReal = (double **)MALLOC(iSize * sizeof(double *));
450 pdblImg = (double **)MALLOC(iSize * sizeof(double *));
451 iRet = readPolyComplexMatrix(_iDatasetId, pstVarName, 2, _pInfo->piDims, piNbCoef, pdblReal, pdblImg);
455 piNbCoef = (int *)MALLOC(iSize * sizeof(int));
456 pdblReal = (double **)MALLOC(iSize * sizeof(double *));
457 iRet = readPolyMatrix(_iDatasetId, pstVarName, 2, _pInfo->piDims, piNbCoef, pdblReal);
460 for (int i = 0 ; i < iSize ; i++)
462 _pInfo->iSize += piNbCoef[i] * 8 * (iComplex + 1);
477 generateInfo(_pInfo, "polynomial");
481 static bool read_list(int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
485 int *piListAddr = NULL;
486 hobj_ref_t *piItemRef = NULL;
488 iRet = getListDims(_iDatasetId, &iItems);
496 //special case for empty list
500 iRet = getListItemReferences(_iDatasetId, &piItemRef);
506 //_pInfo = (VarInfo*)MALLOC(sizeof(VarInfo));
508 _pInfo->piDims[0] = iItems;
509 _pInfo->iSize = (2 + iItems + 1) * 4;
511 for (int i = 0; i < iItems; i++)
513 int iItemDataset = 0;
515 iRet = getListItemDataset(_iDatasetId, piItemRef, i, &iItemDataset);
516 if (iRet || iItemDataset == 0)
521 bool bRet = read_data(iItemDataset, i + 1, piListAddr, &info);
527 _pInfo->iSize += info.iSize;
530 if (_iVarType == sci_list)
532 generateInfo(_pInfo, "list");
534 else if (_iVarType == sci_tlist)
536 generateInfo(_pInfo, "tlist");
538 else if (_iVarType == sci_mlist)
540 generateInfo(_pInfo, "mlist");
543 iRet = deleteListItemReferences(_iDatasetId, piItemRef);
553 static bool read_void(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
556 closeDataSet(_iDatasetId);
560 static bool read_undefined(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
563 closeDataSet(_iDatasetId);
567 static void generateInfo(VarInfo* _pInfo, const char* _pstType)
571 if (_pInfo->iDims == 2)
573 sprintf(pstSize, "%d by %d", _pInfo->piDims[0], _pInfo->piDims[1]);
577 sprintf(pstSize, "%d", _pInfo->piDims[0]);
579 sprintf(_pInfo->pstInfo, "%-*s%-*s%-*s%-*d", 25, _pInfo->varName, 15, _pstType, 16, pstSize, 10, _pInfo->iSize);