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"
30 #include "listvar_in_hdf5_v1.hxx"
33 typedef struct __VAR_INFO__
42 __VAR_INFO__() : iType(0), iSize(0), iDims(0)
44 memset(pstInfo, 0, sizeof(pstInfo) / sizeof(pstInfo[0]));
45 memset(varName, 0, sizeof(varName) / sizeof(varName[0]));
49 static bool read_data(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
50 static bool read_double(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
51 static bool read_string(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
52 static bool read_boolean(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
53 static bool read_integer(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
54 static bool read_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
55 static bool read_boolean_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
56 static bool read_poly(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
57 static bool read_list(int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
58 static bool read_void(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
59 static bool read_undefined(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo);
61 static void generateInfo(VarInfo* _pInfo, const char* _pstType);
63 int sci_listvar_in_hdf5(char *fname, unsigned long fname_len)
70 VarInfo* pInfo = NULL;
71 const int nbIn = nbInputArgument(pvApiCtx);
73 CheckInputArgument(pvApiCtx, 1, 1);
74 CheckOutputArgument(pvApiCtx, 1, 4);
76 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
79 printError(&sciErr, 0);
83 if (getAllocatedSingleString(pvApiCtx, piAddr, &pstFile))
85 Scierror(999, _("%s: Wrong size for input argument #%d: A string expected.\n"), fname, 1);
89 char* pstFileName = expandPathVariable(pstFile);
90 iFile = openHDF5File(pstFileName, 0);
93 Scierror(999, _("%s: Unable to open file: %s\n"), fname, pstFile);
102 //manage version information
103 int iVersion = getSODFormatAttribute(iFile);
104 if (iVersion != SOD_FILE_VERSION)
106 if (iVersion > SOD_FILE_VERSION)
108 //can't read file with version newer that me !
109 closeHDF5File(iFile);
110 Scierror(999, _("%s: Wrong SOD file format version. Max Expected: %d Found: %d\n"), fname, SOD_FILE_VERSION, iVersion);
115 //call older import functions and exit or ... EXIT !
116 if (iVersion == 1 || iVersion == -1)
118 //sciprint("old sci_listvar_in_hdf5_v1\n");
119 return sci_listvar_in_hdf5_v1(fname, fname_len);
124 iNbItem = getVariableNames(iFile, NULL);
127 char** pstVarNameList = (char**)MALLOC(sizeof(char*) * iNbItem);
128 pInfo = (VarInfo*)MALLOC(iNbItem * sizeof(VarInfo));
133 sciprint("Name Type Size Bytes\n");
134 sciprint("---------------------------------------------------------------\n");
137 iNbItem = getVariableNames(iFile, pstVarNameList);
138 for (int i = 0; i < iNbItem; i++)
140 int iDataSetId = getDataSetIdFromName(iFile, pstVarNameList[i]);
146 strcpy(pInfo[i].varName, pstVarNameList[i]);
147 FREE(pstVarNameList[i]);
149 b = read_data(iDataSetId, 0, NULL, &pInfo[i]) == false;
157 sciprint("%s\n", pInfo[i].pstInfo);
161 FREE(pstVarNameList);
165 //no variable returms [] for each Lhs
166 for (int i = 0 ; i < Lhs ; i++)
168 createEmptyMatrix(pvApiCtx, nbIn + i + 1);
169 AssignOutputVariable(pvApiCtx, i + 1) = nbIn + i + 1;
172 ReturnArguments(pvApiCtx);
176 closeHDF5File(iFile);
179 char** pstVarName = (char**)MALLOC(sizeof(char*) * iNbItem);
180 for (int i = 0 ; i < iNbItem ; i++)
182 pstVarName[i] = pInfo[i].varName;
185 sciErr = createMatrixOfString(pvApiCtx, nbIn + 1, iNbItem, 1, pstVarName);
189 printError(&sciErr, 0);
193 AssignOutputVariable(pvApiCtx, 1) = nbIn + 1;
199 sciErr = allocMatrixOfDouble(pvApiCtx, nbIn + 2, iNbItem, 1, &pdblType);
202 printError(&sciErr, 0);
206 for (int i = 0 ; i < iNbItem ; i++)
208 pdblType[i] = pInfo[i].iType;
211 AssignOutputVariable(pvApiCtx, 2) = nbIn + 2;
217 sciErr = createList(pvApiCtx, nbIn + 3, iNbItem, &pList);
218 for (int i = 0 ; i < iNbItem ; i++)
220 double* pdblDims = NULL;
221 allocMatrixOfDoubleInList(pvApiCtx, nbIn + 3, pList, i + 1, 1, pInfo[i].iDims, &pdblDims);
222 for (int j = 0 ; j < pInfo[i].iDims ; j++)
224 pdblDims[j] = pInfo[i].piDims[j];
228 AssignOutputVariable(pvApiCtx, 3) = nbIn + 3;
235 sciErr = allocMatrixOfDouble(pvApiCtx, nbIn + 4, iNbItem, 1, &pdblSize);
236 for (int i = 0 ; i < iNbItem ; i++)
238 pdblSize[i] = pInfo[i].iSize;
241 AssignOutputVariable(pvApiCtx, 4) = nbIn + 4;
247 ReturnArguments(pvApiCtx);
251 static bool read_data(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
255 _pInfo->iType = getScilabTypeFromDataSet(_iDatasetId);
256 switch (_pInfo->iType)
260 bRet = read_double(_iDatasetId, _iItemPos, _piAddress, _pInfo);
265 bRet = read_string(_iDatasetId, _iItemPos, _piAddress, _pInfo);
272 bRet = read_list(_iDatasetId, _pInfo->iType, _iItemPos, _piAddress, _pInfo);
277 bRet = read_boolean(_iDatasetId, _iItemPos, _piAddress, _pInfo);
282 bRet = read_poly(_iDatasetId, _iItemPos, _piAddress, _pInfo);
287 bRet = read_integer(_iDatasetId, _iItemPos, _piAddress, _pInfo);
292 bRet = read_sparse(_iDatasetId, _iItemPos, _piAddress, _pInfo);
295 case sci_boolean_sparse:
297 bRet = read_boolean_sparse(_iDatasetId, _iItemPos, _piAddress, _pInfo);
300 case sci_void: //void item only on list variable
302 bRet = read_void(_iDatasetId, _iItemPos, _piAddress, _pInfo);
305 case sci_undefined: //undefined item only on list variable
307 bRet = read_undefined(_iDatasetId, _iItemPos, _piAddress, _pInfo);
312 Scierror(999, _("%s: Invalid HDF5 Scilab format.\n"), "listvar_in_hdf5");
320 static bool read_double(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
325 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
326 _pInfo->iSize = (2 + (iSize * (iComplex + 1))) * 8;
328 generateInfo(_pInfo, "constant");
329 closeDataSet(_iDatasetId);
333 static bool read_string(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
338 char** pstData = NULL;
340 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
342 pstData = (char **)MALLOC(iSize * sizeof(char *));
343 iRet = readStringMatrix(_iDatasetId, pstData);
346 for (int i = 0 ; i < _pInfo->piDims[0] * _pInfo->piDims[1] ; i++)
348 _pInfo->iSize += (int)strlen(pstData[i]) * 4;
352 freeStringMatrix(_iDatasetId, pstData);
354 //always full double size
355 _pInfo->iSize += (8 - (_pInfo->iSize % 8));
357 _pInfo->iSize += 16 + (1 + iSize) * 4;
359 generateInfo(_pInfo, "string");
363 static bool read_boolean(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
368 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
369 _pInfo->iSize = (3 + iSize) * 4;
371 generateInfo(_pInfo, "boolean");
372 closeDataSet(_iDatasetId);
376 static bool read_integer(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
383 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
384 getDatasetPrecision(_iDatasetId, &iPrec);
386 _pInfo->iSize = 16 + iSize * (iPrec % 10);
388 generateInfo(_pInfo, "integer");
389 closeDataSet(_iDatasetId);
393 static bool read_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
401 iRet = getSparseDimension(_iDatasetId, &iRows, &iCols, &iNbItem);
407 iComplex = isComplexData(_iDatasetId);
410 _pInfo->piDims[0] = iRows;
411 _pInfo->piDims[1] = iCols;
412 _pInfo->iSize = 20 + iRows * 4 + iNbItem * 4 + (iNbItem * (iComplex + 1) * 8);
414 generateInfo(_pInfo, "sparse");
415 closeDataSet(_iDatasetId);
419 static bool read_boolean_sparse(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
427 iRet = getSparseDimension(_iDatasetId, &iRows, &iCols, &iNbItem);
434 _pInfo->piDims[0] = iRows;
435 _pInfo->piDims[1] = iCols;
436 _pInfo->iSize = 20 + iRows * 4 + iNbItem * 4;
438 generateInfo(_pInfo, "boolean sparse");
439 closeDataSet(_iDatasetId);
443 static bool read_poly(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
447 char pstVarName[64] = { 0 };
448 double **pdblReal = NULL;
449 double **pdblImg = NULL;
450 int *piNbCoef = NULL;
453 iSize = getDatasetInfo(_iDatasetId, &iComplex, &_pInfo->iDims, _pInfo->piDims);
454 _pInfo->iSize = 8 * 4 + (iSize + 1) * 4;
458 piNbCoef = (int *)MALLOC(iSize * sizeof(int));
459 pdblReal = (double **)MALLOC(iSize * sizeof(double *));
460 pdblImg = (double **)MALLOC(iSize * sizeof(double *));
461 iRet = readPolyComplexMatrix(_iDatasetId, pstVarName, 2, _pInfo->piDims, piNbCoef, pdblReal, pdblImg);
465 piNbCoef = (int *)MALLOC(iSize * sizeof(int));
466 pdblReal = (double **)MALLOC(iSize * sizeof(double *));
467 iRet = readPolyMatrix(_iDatasetId, pstVarName, 2, _pInfo->piDims, piNbCoef, pdblReal);
470 for (int i = 0 ; i < iSize ; i++)
472 _pInfo->iSize += piNbCoef[i] * 8 * (iComplex + 1);
487 generateInfo(_pInfo, "polynomial");
491 static bool read_list(int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
495 int *piListAddr = NULL;
496 hobj_ref_t *piItemRef = NULL;
498 iRet = getListDims(_iDatasetId, &iItems);
506 //special case for empty list
510 iRet = getListItemReferences(_iDatasetId, &piItemRef);
516 //_pInfo = (VarInfo*)MALLOC(sizeof(VarInfo));
518 _pInfo->piDims[0] = iItems;
519 _pInfo->iSize = (2 + iItems + 1) * 4;
521 for (int i = 0; i < iItems; i++)
523 int iItemDataset = 0;
525 iRet = getListItemDataset(_iDatasetId, piItemRef, i, &iItemDataset);
526 if (iRet || iItemDataset == 0)
531 bool bRet = read_data(iItemDataset, i + 1, piListAddr, &info);
537 _pInfo->iSize += info.iSize;
540 if (_iVarType == sci_list)
542 generateInfo(_pInfo, "list");
544 else if (_iVarType == sci_tlist)
546 generateInfo(_pInfo, "tlist");
548 else if (_iVarType == sci_mlist)
550 generateInfo(_pInfo, "mlist");
553 iRet = deleteListItemReferences(_iDatasetId, piItemRef);
563 static bool read_void(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
566 closeDataSet(_iDatasetId);
570 static bool read_undefined(int _iDatasetId, int _iItemPos, int *_piAddress, VarInfo* _pInfo)
573 closeDataSet(_iDatasetId);
577 static void generateInfo(VarInfo* _pInfo, const char* _pstType)
581 if (_pInfo->iDims == 2)
583 sprintf(pstSize, "%d by %d", _pInfo->piDims[0], _pInfo->piDims[1]);
585 else if (_pInfo->iDims == 1)
587 sprintf(pstSize, "%d", _pInfo->piDims[0]);
594 sprintf(_pInfo->pstInfo, "%-*s%-*s%-*s%-*d", 25, _pInfo->varName, 15, _pstType, 16, pstSize, 10, _pInfo->iSize);