2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009 - 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
21 #include "localization.h"
23 #include "api_scilab.h"
24 #include "deleteafile.h"
25 #include "expandPathVariable.h"
26 #include "h5_fileManagement.h"
27 #include "h5_writeDataToFile.h"
28 #include "h5_readDataFromFile.h"
29 #include "h5_attributeConstants.h"
30 #include "freeArrayOfString.h"
32 #include "strdup_windows.h"
34 #include "scilabmode.h"
35 #include "splitpath.h"
36 #include "scicurdir.h"
42 static bool isVarExist(int _iFile, char* _pstVarName);
44 static bool export_data(int _iH5File, int *_piVar, char* _pstName);
45 static bool export_list(int _iH5File, int *_piVar, char* _pstName, int _iVarType);
46 static bool export_double(int _iH5File, int *_piVar, char* _pstName);
47 static bool export_poly(int _iH5File, int *_piVar, char* _pstName);
48 static bool export_boolean(int _iH5File, int *_piVar, char* _pstName);
49 static bool export_sparse(int _iH5File, int *_piVar, char* _pstName);
50 static bool export_boolean_sparse(int _iH5File, int *_piVar, char* _pstName);
51 static bool export_matlab_sparse(int *_piVar, char* _pstName);
52 static bool export_ints(int _iH5File, int *_piVar, char* _pstName);
53 static bool export_handles(int *_piVar, char* _pstName);
54 static bool export_strings(int _iH5File, int *_piVar, char* _pstName);
55 static bool export_u_function(int *_piVar, char* _pstName);
56 static bool export_c_function(int *_piVar, char* _pstName);
57 static bool export_lib(int *_piVar, char* _pstName);
58 static bool export_lufact_pointer(int *_piVar, char* _pstName);
59 static bool export_void(int _iH5File, int *_piVar, char* _pstName);
61 void print_type(char* _pstType);
62 int extractVarNameList(int _iStart, int _iEnd, char** _pstNameList);
65 /*--------------------------------------------------------------------------*/
66 int sci_export_to_hdf5(char *fname, unsigned long fname_len)
69 int** piAddrList = NULL;
70 char** pstNameList = NULL;
71 char *pstFileName = NULL;
73 bool bAppendMode = false;
77 int iRhs = nbInputArgument(pvApiCtx);
78 CheckInputArgumentAtLeast(pvApiCtx, 1);
79 CheckOutputArgument(pvApiCtx, 0, 1);
81 pstNameList = (char**)MALLOC(sizeof(char*) * iRhs);
82 iNbVar = extractVarNameList(1, iRhs, pstNameList);
89 piAddrList = (int**)MALLOC(sizeof(int*) * (iNbVar));
90 for (int i = 1 ; i < iRhs ; i++)
92 if (strcmp(pstNameList[i], "-append") == 0)
98 sciErr = getVarAddressFromName(pvApiCtx, pstNameList[i], &piAddrList[i]);
101 freeArrayOfString(pstNameList, iRhs);
103 Scierror(999, _("%s: Wrong value for input argument #%d: Defined variable expected.\n"), fname, i + 1);
104 printError(&sciErr, 0);
112 pstFileName = expandPathVariable(pstNameList[0]);
116 iH5File = openHDF5File(pstFileName, bAppendMode);
119 iH5File = createHDF5File(pstFileName);
124 iH5File = createHDF5File(pstFileName);
132 Scierror(999, _("%s: Wrong value for input argument #%d: \"%s\" is a directory"), fname, 1, pstNameList[0]);
136 Scierror(999, _("%s: Cannot open file %s.\n"), fname, pstNameList[0]);
140 freeArrayOfString(pstNameList, iRhs);
147 int iVersion = getSODFormatAttribute(iH5File);
148 if (iVersion != -1 && iVersion != SOD_FILE_VERSION)
150 //to update version must be the same
151 closeHDF5File(iH5File);
152 Scierror(999, _("%s: Wrong SOD file format version. Expected: %d Found: %d\n"), fname, SOD_FILE_VERSION, iVersion);
154 freeArrayOfString(pstNameList, iRhs);
161 for (int i = 1 ; i < iRhs ; i++)
163 if (strcmp(pstNameList[i], "-append") == 0)
168 if (isVarExist(iH5File, pstNameList[i]))
172 if (deleteHDF5Var(iH5File, pstNameList[i]))
174 closeHDF5File(iH5File);
175 Scierror(999, _("%s: Unable to delete existing variable \"%s\"."), fname, pstNameList[i]);
177 freeArrayOfString(pstNameList, iRhs);
184 closeHDF5File(iH5File);
185 Scierror(999, _("%s: Variable \'%s\' already exists in file \'%s\'\nUse -append option to replace existing variable\n."), fname, pstNameList[i], pstNameList[0]);
187 freeArrayOfString(pstNameList, iRhs);
193 bExport = export_data(iH5File, piAddrList[i], pstNameList[i]);
194 if (bExport == false)
200 if (bExport && iRhs != 1)
202 //add or update scilab version and file version in hdf5 file
203 if (updateScilabVersion(iH5File) < 0)
205 closeHDF5File(iH5File);
206 Scierror(999, _("%s: Unable to update Scilab version in \"%s\"."), fname, pstNameList[0]);
208 freeArrayOfString(pstNameList, iRhs);
213 if (updateFileVersion(iH5File) < 0)
215 closeHDF5File(iH5File);
216 Scierror(999, _("%s: Unable to update HDF5 format version in \"%s\"."), fname, pstNameList[0]);
218 freeArrayOfString(pstNameList, iRhs);
225 closeHDF5File(iH5File);
227 //delete file in case of error but nor in append mode
228 if (bExport == false && bAppendMode == false && iRhs != 1)
231 deleteafile(pstFileName);
235 freeArrayOfString(pstNameList, iRhs);
238 //create boolean return value
239 int *piReturn = NULL;
240 sciErr = allocMatrixOfBoolean(pvApiCtx, iRhs + 1, 1, 1, &piReturn);
243 printError(&sciErr, 0);
247 if (bExport == true || iRhs == 1)
256 LhsVar(1) = iRhs + 1;
261 static bool export_data(int _iH5File, int* _piVar, char* _pstName)
263 bool bReturn = false;
266 SciErr sciErr = getVarType(pvApiCtx, _piVar, &iType);
269 printError(&sciErr, 0);
277 bReturn = export_double(_iH5File, _piVar, _pstName);
282 bReturn = export_poly(_iH5File, _piVar, _pstName);
287 bReturn = export_boolean(_iH5File, _piVar, _pstName);
292 bReturn = export_sparse(_iH5File, _piVar, _pstName);
295 case sci_boolean_sparse :
297 bReturn = export_boolean_sparse(_iH5File, _piVar, _pstName);
300 case sci_matlab_sparse :
302 bReturn = export_matlab_sparse(_piVar, _pstName);
307 bReturn = export_ints(_iH5File, _piVar, _pstName);
312 bReturn = export_handles(_piVar, _pstName);
317 bReturn = export_strings(_iH5File, _piVar, _pstName);
320 case sci_u_function :
322 bReturn = export_u_function(_piVar, _pstName);
325 case sci_c_function :
327 bReturn = export_c_function(_piVar, _pstName);
332 bReturn = export_lib(_piVar, _pstName);
339 bReturn = export_list(_iH5File, _piVar, _pstName, iType);
342 case sci_lufact_pointer :
344 bReturn = export_lufact_pointer(_piVar, _pstName);
347 case 0 : //void case to "null" items in list
349 bReturn = export_void(_iH5File, _piVar, _pstName);
362 static bool export_void(int _iH5File, int *_piVar, char* _pstName)
364 int iRet = writeVoid(_iH5File, _pstName);
370 //char pstMsg[] = "void";
371 //print_type(pstMsg);
375 static bool export_undefined(int _iH5File, int *_piVar, char* _pstName)
377 int iRet = writeUndefined(_iH5File, _pstName);
383 //char pstMsg[] = "void";
384 //print_type(pstMsg);
388 static bool export_list(int _iH5File, int *_piVar, char* _pstName, int _iVarType)
391 bool bReturn = false;
393 SciErr sciErr = getListItemNumber(pvApiCtx, _piVar, &iItemNumber);
396 printError(&sciErr, 0);
402 char* pstGroupName = createGroupName(_pstName);
405 //sprintf(pstMsg, "list (%d)", iItemNumber);
406 //print_type(pstMsg);
410 void *pvList = openList(_iH5File, pstGroupName, iItemNumber);
411 for (int i = 0 ; i < iItemNumber ; i++)
413 int *piNewVar = NULL;
414 getListItemAddress(pvApiCtx, _piVar, i + 1, &piNewVar);//1 indexed
415 char* pstPathName = createPathName(pstGroupName, i);
417 if (piNewVar == NULL)
420 bReturn = export_undefined(_iH5File, piNewVar, pstPathName);
424 bReturn = export_data(_iH5File, piNewVar, pstPathName);
427 iRet = addItemInList(_iH5File, pvList, i, pstPathName);
429 if (bReturn == false || iRet)
435 closeList(_iH5File, pvList, _pstName, iItemNumber, _iVarType);
441 static bool export_double(int _iH5File, int *_piVar, char* _pstName)
444 int iComplex = isVarComplex(pvApiCtx, _piVar);
447 double *pdblReal = NULL;
448 double *pdblImg = NULL;
450 SciErr sciErr = getVarType(pvApiCtx, _piVar, &iType);
453 printError(&sciErr, 0);
457 if (iType != sci_matrix)
464 sciErr = getComplexMatrixOfDouble(pvApiCtx, _piVar, &piDims[0], &piDims[1], &pdblReal, &pdblImg);
467 printError(&sciErr, 0);
471 iRet = writeDoubleComplexMatrix(_iH5File, _pstName, 2, piDims, pdblReal, pdblImg);
475 sciErr = getMatrixOfDouble(pvApiCtx, _piVar, &piDims[0], &piDims[1], &pdblReal);
478 printError(&sciErr, 0);
482 iRet = writeDoubleMatrix(_iH5File, _pstName, 2, piDims, pdblReal);
491 //sprintf(pstMsg, "double (%d x %d)", piDims[0], piDims[1]);
492 //print_type(pstMsg);
496 static bool export_poly(int _iH5File, int *_piVar, char* _pstName)
499 int* piNbCoef = NULL;
500 double** pdblReal = NULL;
501 double** pdblImg = NULL;
502 char pstVarName[64] = {0};
506 SciErr sciErr = getPolyVariableName(pvApiCtx, _piVar, pstVarName, &iVarNameLen);
509 printError(&sciErr, 0);
513 if (isVarComplex(pvApiCtx, _piVar))
515 if (getAllocatedMatrixOfComplexPoly(pvApiCtx, _piVar, &piDims[0], &piDims[1], &piNbCoef, &pdblReal, &pdblImg))
517 freeAllocatedMatrixOfComplexPoly(piDims[0], piDims[1], piNbCoef, pdblReal, pdblImg);
521 iRet = writePolyComplexMatrix(_iH5File, _pstName, pstVarName, 2, piDims, piNbCoef, pdblReal, pdblImg);
522 freeAllocatedMatrixOfComplexPoly(piDims[0], piDims[1], piNbCoef, pdblReal, pdblImg);
526 if (getAllocatedMatrixOfPoly(pvApiCtx, _piVar, &piDims[0], &piDims[1], &piNbCoef, &pdblReal))
528 freeAllocatedMatrixOfPoly(piDims[0], piDims[1], piNbCoef, pdblReal);
532 iRet = writePolyMatrix(_iH5File, _pstName, pstVarName, 2, piDims, piNbCoef, pdblReal);
533 freeAllocatedMatrixOfPoly(piDims[0], piDims[1], piNbCoef, pdblReal);
542 //sprintf(pstMsg, "poly (%d x %d)", piDims[0], piDims[1]);
543 //print_type(pstMsg);
547 static bool export_boolean(int _iH5File, int *_piVar, char* _pstName)
552 //for error management
553 SciErr sciErr = getMatrixOfBoolean(pvApiCtx, _piVar, &piDims[0], &piDims[1], &piData);
556 printError(&sciErr, 0);
560 int iRet = writeBooleanMatrix(_iH5File, _pstName, 2, piDims, piData);
568 //sprintf(pstMsg, "bool (%d x %d)", piDims[0], piDims[1]);
569 //print_type(pstMsg);
573 static bool export_boolean_sparse(int _iH5File, int *_piVar, char* _pstName)
577 int* piNbItemRow = NULL;
578 int* piColPos = NULL;
581 SciErr sciErr = getBooleanSparseMatrix(pvApiCtx, _piVar, &piDims[0], &piDims[1], &iNbItem, &piNbItemRow, &piColPos);
584 printError(&sciErr, 0);
588 iRet = writeBooleanSparseMatrix(_iH5File, _pstName, piDims[0], piDims[1], iNbItem, piNbItemRow, piColPos);
596 //sprintf(pstMsg, "boolean sparse (%d x %d)", piDims[0], piDims[1]);
597 //print_type(pstMsg);
601 static bool export_sparse(int _iH5File, int *_piVar, char* _pstName)
605 int* piNbItemRow = NULL;
606 int* piColPos = NULL;
607 double* pdblReal = NULL;
608 double* pdblImg = NULL;
612 if (isVarComplex(pvApiCtx, _piVar))
614 sciErr = getComplexSparseMatrix(pvApiCtx, _piVar, &piDims[0], &piDims[1], &iNbItem, &piNbItemRow, &piColPos, &pdblReal, &pdblImg);
617 printError(&sciErr, 0);
621 iRet = writeSparseComplexMatrix(_iH5File, _pstName, piDims[0], piDims[1], iNbItem, piNbItemRow, piColPos, pdblReal, pdblImg);
625 sciErr = getSparseMatrix(pvApiCtx, _piVar, &piDims[0], &piDims[1], &iNbItem, &piNbItemRow, &piColPos, &pdblReal);
628 printError(&sciErr, 0);
632 iRet = writeSparseMatrix(_iH5File, _pstName, piDims[0], piDims[1], iNbItem, piNbItemRow, piColPos, pdblReal);
641 //sprintf(pstMsg, "sparse (%d x %d)", piDims[0], piDims[1]);
642 //print_type(pstMsg);
646 static bool export_matlab_sparse(int *_piVar, char* _pstName)
648 //print_type(_pstName);
652 static bool export_ints(int _iH5File, int *_piVar, char* _pstName)
659 SciErr sciErr = getMatrixOfIntegerPrecision(pvApiCtx, _piVar, &iPrec);
662 printError(&sciErr, 0);
669 sciErr = getMatrixOfInteger8(pvApiCtx, _piVar, &piDims[0], &piDims[1], (char**)&piData);
672 printError(&sciErr, 0);
675 iRet = writeInteger8Matrix(_iH5File, _pstName, 2, piDims, (char*)piData);
678 sciErr = getMatrixOfUnsignedInteger8(pvApiCtx, _piVar, &piDims[0], &piDims[1], (unsigned char**)&piData);
681 printError(&sciErr, 0);
684 iRet = writeUnsignedInteger8Matrix(_iH5File, _pstName, 2, piDims, (unsigned char*)piData);
687 sciErr = getMatrixOfInteger16(pvApiCtx, _piVar, &piDims[0], &piDims[1], (short**)&piData);
690 printError(&sciErr, 0);
693 iRet = writeInteger16Matrix(_iH5File, _pstName, 2, piDims, (short*)piData);
696 sciErr = getMatrixOfUnsignedInteger16(pvApiCtx, _piVar, &piDims[0], &piDims[1], (unsigned short**)&piData);
699 printError(&sciErr, 0);
702 iRet = writeUnsignedInteger16Matrix(_iH5File, _pstName, 2, piDims, (unsigned short*)piData);
705 sciErr = getMatrixOfInteger32(pvApiCtx, _piVar, &piDims[0], &piDims[1], (int**)&piData);
708 printError(&sciErr, 0);
711 iRet = writeInteger32Matrix(_iH5File, _pstName, 2, piDims, (int*)piData);
714 sciErr = getMatrixOfUnsignedInteger32(pvApiCtx, _piVar, &piDims[0], &piDims[1], (unsigned int**)&piData);
717 printError(&sciErr, 0);
720 iRet = writeUnsignedInteger32Matrix(_iH5File, _pstName, 2, piDims, (unsigned int*)piData);
723 //sciErr = getMatrixOfInteger64(_piVar, &piDims[0], &piDims[1], (long long**)&piData);
726 // printError(&sciErr, 0);
729 //iRet = writeInteger64Matrix(_iH5File, _pstName, 2, piDims, (long long*)piData);
732 //sciErr = getMatrixOfUnsignedInteger64(_piVar, &piDims[0], &piDims[1], (unsigned long long**)&piData);
735 // printError(&sciErr, 0);
738 //iRet = writeUnsignedInteger64Matrix(_iH5File, _pstName, 2, piDims, (unsigned long long*)piData);
751 //sprintf(pstMsg, "int%d (%d x %d)", 8 * iPrec, piDims[0], piDims[1]);
752 //print_type(pstMsg);
756 static bool export_handles(int *_piVar, char* _pstName)
758 //print_type(_pstName);
762 static bool export_strings(int _iH5File, int *_piVar, char* _pstName)
765 char** pstData = NULL;
768 SciErr sciErr = getMatrixOfString(pvApiCtx, _piVar, &piDims[0], &piDims[1], NULL, NULL);
771 printError(&sciErr, 0);
775 if (getAllocatedMatrixOfString(pvApiCtx, _piVar, &piDims[0], &piDims[1], &pstData))
779 freeAllocatedMatrixOfString(piDims[0], piDims[1], pstData);
785 iRet = writeStringMatrix(_iH5File, _pstName, 2, piDims, pstData);
786 freeAllocatedMatrixOfString(piDims[0], piDims[1], pstData);
793 //sprintf(pstMsg, "string (%d x %d)", piDims[0], piDims[1]);
794 //print_type(pstMsg);
799 static bool export_u_function(int *_piVar, char* _pstName)
801 //print_type(_pstName);
805 static bool export_c_function(int *_piVar, char* _pstName)
807 //print_type(_pstName);
811 static bool export_lib(int *_piVar, char* _pstName)
813 //print_type(_pstName);
817 static bool export_lufact_pointer(int *_piVar, char* _pstName)
819 /*print_type*/(_pstName);
823 void print_type(char* _pstType)
826 for (int i = 0 ; i < iLevel ; i++)
830 sciprint("%s\n", _pstType);
834 int extractVarNameList(int _iStart, int _iEnd, char** _pstNameList)
838 for (int i = _iStart ; i <= _iEnd ; i++)
843 SciErr sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddr);
846 printError(&sciErr, 0);
850 if (getAllocatedSingleString(pvApiCtx, piAddr, &_pstNameList[iCount]))
852 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "export_to_hdf5", i);
861 static bool isVarExist(int _iFile, char* _pstVarName)
863 //check if variable already exists
864 int iNbItem = getVariableNames(_iFile, NULL);
867 char **pstVarNameList = (char **)MALLOC(sizeof(char *) * iNbItem);
869 iNbItem = getVariableNames(_iFile, pstVarNameList);
872 for (int i = 0 ; i < iNbItem ; i++)
874 if (strcmp(pstVarNameList[i], _pstVarName) == 0)
880 freeArrayOfString(pstVarNameList, iNbItem);
885 /*--------------------------------------------------------------------------*/