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.1-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"
28 #include "freeArrayOfString.h"
31 #include "listvar_in_hdf5_v1.hxx"
34 typedef struct __VAR_INFO__
43 __VAR_INFO__() : iType(0), iSize(0), iDims(0)
45 memset(pstInfo, 0, sizeof(pstInfo) / sizeof(pstInfo[0]));
46 memset(varName, 0, sizeof(varName) / sizeof(varName[0]));
50 static bool read_data(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
51 static bool read_double(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
52 static bool read_string(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
53 static bool read_boolean(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
54 static bool read_integer(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
55 static bool read_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
56 static bool read_boolean_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
57 static bool read_poly(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
58 static bool read_list(int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
59 static bool read_void(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
60 static bool read_undefined(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
62 static void generateInfo(VarInfo* _pInfo, const char* _pstType);
64 int sci_listvar_in_hdf5(char *fname, unsigned long fname_len)
71 VarInfo* pInfo = NULL;
72 const int nbIn = nbInputArgument(pvApiCtx);
74 CheckInputArgument(pvApiCtx, 1, 1);
75 CheckOutputArgument(pvApiCtx, 1, 4);
77 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
80 printError(&sciErr, 0);
84 if (getAllocatedSingleString(pvApiCtx, piAddr, &pstFile))
91 Scierror(999, _("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 1);
95 char* pstFileName = expandPathVariable(pstFile);
96 iFile = openHDF5File(pstFileName, 0);
99 Scierror(999, _("%s: Unable to open file: %s\n"), fname, pstFile);
108 //manage version information
109 int iVersion = getSODFormatAttribute(iFile);
110 if (iVersion != SOD_FILE_VERSION)
112 if (iVersion > SOD_FILE_VERSION)
114 //can't read file with version newer that me !
115 closeHDF5File(iFile);
116 Scierror(999, _("%s: Wrong SOD file format version. Max Expected: %d Found: %d\n"), fname, SOD_FILE_VERSION, iVersion);
121 //call older import functions and exit or ... EXIT !
122 if (iVersion == 1 || iVersion == -1)
124 //sciprint("old sci_listvar_in_hdf5_v1\n");
125 return sci_listvar_in_hdf5_v1(fname, fname_len);
130 iNbItem = getVariableNames(iFile, NULL);
133 char** pstVarNameList = (char**)MALLOC(sizeof(char*) * iNbItem);
134 pInfo = (VarInfo*)MALLOC(iNbItem * sizeof(VarInfo));
139 sciprint("Name Type Size Bytes\n");
140 sciprint("---------------------------------------------------------------\n");
143 iNbItem = getVariableNames(iFile, pstVarNameList);
144 for (int i = 0; i < iNbItem; i++)
146 int iDataSetId = getDataSetIdFromName(iFile, pstVarNameList[i]);
152 strncpy(pInfo[i].varName, pstVarNameList[i], sizeof(pInfo[i].varName));
154 b = read_data(iDataSetId, 0, NULL, &pInfo[i]) == false;
162 sciprint("%s\n", pInfo[i].pstInfo);
166 freeArrayOfString(pstVarNameList, iNbItem);
170 //no variable returms [] for each Lhs
171 for (int i = 0 ; i < Lhs ; i++)
173 createEmptyMatrix(pvApiCtx, nbIn + i + 1);
174 AssignOutputVariable(pvApiCtx, i + 1) = nbIn + i + 1;
177 ReturnArguments(pvApiCtx);
181 closeHDF5File(iFile);
184 char** pstVarName = (char**)MALLOC(sizeof(char*) * iNbItem);
185 for (int i = 0 ; i < iNbItem ; i++)
187 pstVarName[i] = pInfo[i].varName;
190 sciErr = createMatrixOfString(pvApiCtx, nbIn + 1, iNbItem, 1, pstVarName);
195 printError(&sciErr, 0);
199 AssignOutputVariable(pvApiCtx, 1) = nbIn + 1;
205 sciErr = allocMatrixOfDouble(pvApiCtx, nbIn + 2, iNbItem, 1, &pdblType);
208 printError(&sciErr, 0);
213 for (int i = 0 ; i < iNbItem ; i++)
215 pdblType[i] = pInfo[i].iType;
218 AssignOutputVariable(pvApiCtx, 2) = nbIn + 2;
224 sciErr = createList(pvApiCtx, nbIn + 3, iNbItem, &pList);
225 for (int i = 0 ; i < iNbItem ; i++)
227 double* pdblDims = NULL;
228 allocMatrixOfDoubleInList(pvApiCtx, nbIn + 3, pList, i + 1, 1, pInfo[i].iDims, &pdblDims);
229 for (int j = 0 ; j < pInfo[i].iDims ; j++)
231 pdblDims[j] = pInfo[i].piDims[j];
235 AssignOutputVariable(pvApiCtx, 3) = nbIn + 3;
241 double* pdblSize = NULL;
242 sciErr = allocMatrixOfDouble(pvApiCtx, nbIn + 4, iNbItem, 1, &pdblSize);
243 for (int i = 0 ; i < iNbItem ; i++)
245 pdblSize[i] = pInfo[i].iSize;
248 AssignOutputVariable(pvApiCtx, 4) = nbIn + 4;
254 ReturnArguments(pvApiCtx);
258 static bool read_data(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
262 _pInfo->iType = getScilabTypeFromDataSet(_iDatasetId);
263 switch (_pInfo->iType)
267 bRet = read_double(_iDatasetId, _iItemPos, _piAddress, _pInfo);
272 bRet = read_string(_iDatasetId, _iItemPos, _piAddress, _pInfo);
279 bRet = read_list(_iDatasetId, _pInfo->iType, _iItemPos, _piAddress, _pInfo);
284 bRet = read_boolean(_iDatasetId, _iItemPos, _piAddress, _pInfo);
289 bRet = read_poly(_iDatasetId, _iItemPos, _piAddress, _pInfo);
294 bRet = read_integer(_iDatasetId, _iItemPos, _piAddress, _pInfo);
299 bRet = read_sparse(_iDatasetId, _iItemPos, _piAddress, _pInfo);
302 case sci_boolean_sparse:
304 bRet = read_boolean_sparse(_iDatasetId, _iItemPos, _piAddress, _pInfo);
307 case sci_void: //void item only on list variable
309 bRet = read_void(_iDatasetId, _iItemPos, _piAddress, _pInfo);
312 case sci_undefined: //undefined item only on list variable
314 bRet = read_undefined(_iDatasetId, _iItemPos, _piAddress, _pInfo);
319 Scierror(999, _("%s: Invalid HDF5 Scilab format.\n"), "listvar_in_hdf5");
327 static bool read_double(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
332 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
333 _pInfo->iSize = (2 + (iSize * (iComplex + 1))) * 8;
335 generateInfo(_pInfo, "constant");
336 closeDataSet(_iDatasetId);
340 static bool read_string(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
345 char** pstData = NULL;
347 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
349 pstData = (char **)MALLOC(iSize * sizeof(char *));
350 iRet = readStringMatrix(_iDatasetId, pstData);
353 for (int i = 0 ; i < _pInfo->piDims[0] * _pInfo->piDims[1] ; i++)
355 _pInfo->iSize += (int)strlen(pstData[i]) * 4;
359 freeStringMatrix(_iDatasetId, pstData);
361 //always full double size
362 _pInfo->iSize += (8 - (_pInfo->iSize % 8));
364 _pInfo->iSize += 16 + (1 + iSize) * 4;
366 generateInfo(_pInfo, "string");
370 static bool read_boolean(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
375 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
376 _pInfo->iSize = (3 + iSize) * 4;
378 generateInfo(_pInfo, "boolean");
379 closeDataSet(_iDatasetId);
383 static bool read_integer(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
390 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
391 getDatasetPrecision(_iDatasetId, &iPrec);
393 _pInfo->iSize = 16 + iSize * (iPrec % 10);
395 generateInfo(_pInfo, "integer");
396 closeDataSet(_iDatasetId);
400 static bool read_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
408 iRet = getSparseDimension(_iDatasetId, &iRows, &iCols, &iNbItem);
414 iComplex = isComplexData(_iDatasetId);
417 _pInfo->piDims[0] = iRows;
418 _pInfo->piDims[1] = iCols;
419 _pInfo->iSize = 20 + iRows * 4 + iNbItem * 4 + (iNbItem * (iComplex + 1) * 8);
421 generateInfo(_pInfo, "sparse");
422 closeDataSet(_iDatasetId);
426 static bool read_boolean_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
434 iRet = getSparseDimension(_iDatasetId, &iRows, &iCols, &iNbItem);
441 _pInfo->piDims[0] = iRows;
442 _pInfo->piDims[1] = iCols;
443 _pInfo->iSize = 20 + iRows * 4 + iNbItem * 4;
445 generateInfo(_pInfo, "boolean sparse");
446 closeDataSet(_iDatasetId);
450 static bool read_poly(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
454 char pstVarName[64] = { 0 };
455 double **pdblReal = NULL;
456 double **pdblImg = NULL;
457 int *piNbCoef = NULL;
460 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
461 _pInfo->iSize = 8 * 4 + (iSize + 1) * 4;
465 piNbCoef = (int *)MALLOC(iSize * sizeof(int));
466 pdblReal = (double **)MALLOC(iSize * sizeof(double *));
467 pdblImg = (double **)MALLOC(iSize * sizeof(double *));
468 iRet = readPolyComplexMatrix(_iDatasetId, pstVarName, 2, _pInfo->piDims, piNbCoef, pdblReal, pdblImg);
472 piNbCoef = (int *)MALLOC(iSize * sizeof(int));
473 pdblReal = (double **)MALLOC(iSize * sizeof(double *));
474 iRet = readPolyMatrix(_iDatasetId, pstVarName, 2, _pInfo->piDims, piNbCoef, pdblReal);
477 for (int i = 0 ; i < iSize ; i++)
479 _pInfo->iSize += piNbCoef[i] * 8 * (iComplex + 1);
494 generateInfo(_pInfo, "polynomial");
498 static bool read_list(int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
502 int *piListAddr = NULL;
503 hobj_ref_t *piItemRef = NULL;
505 iRet = getListDims(_iDatasetId, &iItems);
513 //special case for empty list
517 iRet = getListItemReferences(_iDatasetId, &piItemRef);
523 //_pInfo = (VarInfo*)MALLOC(sizeof(VarInfo));
525 _pInfo->piDims[0] = iItems;
526 _pInfo->iSize = (2 + iItems + 1) * 4;
528 for (int i = 0; i < iItems; i++)
530 int iItemDataset = 0;
532 iRet = getListItemDataset(_iDatasetId, piItemRef, i, &iItemDataset);
533 if (iRet || iItemDataset == 0)
538 bool bRet = read_data(iItemDataset, i + 1, piListAddr, &info);
544 _pInfo->iSize += info.iSize;
547 if (_iVarType == sci_list)
549 generateInfo(_pInfo, "list");
551 else if (_iVarType == sci_tlist)
553 generateInfo(_pInfo, "tlist");
555 else if (_iVarType == sci_mlist)
557 generateInfo(_pInfo, "mlist");
560 iRet = deleteListItemReferences(_iDatasetId, piItemRef);
570 static bool read_void(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
573 closeDataSet(_iDatasetId);
577 static bool read_undefined(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
580 closeDataSet(_iDatasetId);
584 static void generateInfo(VarInfo* _pInfo, const char* _pstType)
588 if (_pInfo->iDims == 2)
590 sprintf(pstSize, "%d by %d", _pInfo->piDims[0], _pInfo->piDims[1]);
592 else if (_pInfo->iDims == 1)
594 sprintf(pstSize, "%d", _pInfo->piDims[0]);
601 sprintf(_pInfo->pstInfo, "%-*s%-*s%-*s%-*d", 25, _pInfo->varName, 15, _pstType, 16, pstSize, 10, _pInfo->iSize);