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-en.txt
20 #include "localization.h"
22 #include "api_scilab.h"
23 #include "deleteafile.h"
24 #include "expandPathVariable.h"
25 #include "h5_fileManagement.h"
26 #include "h5_writeDataToFile.h"
27 #include "h5_readDataFromFile.h"
28 #include "h5_attributeConstants.h"
29 #include "freeArrayOfString.h"
31 #include "strdup_windows.h"
33 #include "scilabmode.h"
34 #include "splitpath.h"
35 #include "scicurdir.h"
37 #include "forceJHDF5load.hxx"
42 static bool export_data(int _iH5File, int *_piVar, char* _pstName);
43 static bool export_list(int _iH5File, int *_piVar, char* _pstName, int _iVarType);
44 static bool export_double(int _iH5File, int *_piVar, char* _pstName);
45 static bool export_poly(int _iH5File, int *_piVar, char* _pstName);
46 static bool export_boolean(int _iH5File, int *_piVar, char* _pstName);
47 static bool export_sparse(int _iH5File, int *_piVar, char* _pstName);
48 static bool export_boolean_sparse(int _iH5File, int *_piVar, char* _pstName);
49 static bool export_matlab_sparse(int *_piVar, char* _pstName);
50 static bool export_ints(int _iH5File, int *_piVar, char* _pstName);
51 static bool export_handles(int *_piVar, char* _pstName);
52 static bool export_strings(int _iH5File, int *_piVar, char* _pstName);
53 static bool export_u_function(int *_piVar, char* _pstName);
54 static bool export_c_function(int *_piVar, char* _pstName);
55 static bool export_lib(int *_piVar, char* _pstName);
56 static bool export_lufact_pointer(int *_piVar, char* _pstName);
57 static bool export_void(int _iH5File, int *_piVar, char* _pstName);
59 void print_type(char* _pstType);
60 int extractVarNameList(int _iStart, int _iEnd, char** _pstNameList);
63 /*--------------------------------------------------------------------------*/
64 int sci_export_to_hdf5(char *fname, unsigned long fname_len)
67 int** piAddrList = NULL;
68 char** pstNameList = NULL;
69 char *pstFileName = NULL;
71 bool bAppendMode = false;
75 CheckInputArgumentAtLeast(pvApiCtx, 2);
82 pstNameList = (char**)MALLOC(sizeof(char*) * Rhs);
83 iNbVar = extractVarNameList(1, Rhs, pstNameList);
90 piAddrList = (int**)MALLOC(sizeof(int*) * (iNbVar));
91 for (int i = 1 ; i < Rhs ; i++)
93 if (strcmp(pstNameList[i], "-append") == 0)
99 sciErr = getVarAddressFromName(pvApiCtx, pstNameList[i], &piAddrList[i]);
102 Scierror(999, _("%s: Wrong value for input argument #%d: Defined variable expected.\n"), fname, i + 1);
103 printError(&sciErr, 0);
109 //check append option
113 pstFileName = expandPathVariable(pstNameList[0]);
117 iH5File = openHDF5File(pstFileName);
120 iH5File = createHDF5File(pstFileName);
125 iH5File = createHDF5File(pstFileName);
134 Scierror(999, _("%s: Wrong value for input argument #%d: \"%s\" is a directory"), fname, 1, pstNameList[0]);
138 Scierror(999, _("%s: Cannot open file %s.\n"), fname, pstNameList[0]);
146 int iVersion = getSODFormatAttribute(iH5File);
147 if (iVersion != -1 && iVersion != SOD_FILE_VERSION)
149 Scierror(999, _("%s: Wrong hdf5 file format version. Expected: %d from file: %d\n"), fname, SOD_FILE_VERSION, iVersion);
153 //check if variable already exists
154 int iNbItem = getVariableNames(iH5File, NULL);
157 char **pstVarNameList = (char **)MALLOC(sizeof(char *) * iNbItem);
159 iNbItem = getVariableNames(iH5File, pstVarNameList);
162 for (int i = 0 ; i < iNbItem ; i++)
164 for (int j = 1 ; j < Rhs ; j++)
166 if (strcmp(pstNameList[i], "-append") == 0)
171 if (strcmp(pstVarNameList[i], pstNameList[j]) == 0)
174 Scierror(999, _("%s: Variable \'%s\' already exists in file \'%s\'."), fname, pstVarNameList[i], pstNameList[0]);
178 FREE(pstVarNameList[i]);
180 FREE(pstVarNameList);
185 for (int i = 1 ; i < Rhs ; i++)
187 if (strcmp(pstNameList[i], "-append") == 0)
192 bExport = export_data(iH5File, piAddrList[i], pstNameList[i]);
193 if (bExport == false)
201 //add or update scilab version and file version in hdf5 file
202 if (updateScilabVersion(iH5File) < 0)
204 Scierror(999, _("%s: Unable to update Scilab version in \"%s\"."), fname, pstNameList[0]);
208 if (updateFileVersion(iH5File) < 0)
210 Scierror(999, _("%s: Unable to update HDF5 format version in \"%s\"."), fname, pstNameList[0]);
216 closeHDF5File(iH5File);
217 if (bExport == false)
220 deleteafile(pstFileName);
224 //create boolean return value
225 int *piReturn = NULL;
226 sciErr = allocMatrixOfBoolean(pvApiCtx, Rhs + 1, 1, 1, &piReturn);
229 printError(&sciErr, 0);
244 for (int i = 0 ; i < Rhs ; i++)
246 FREE(pstNameList[i]);
257 static bool export_data(int _iH5File, int* _piVar, char* _pstName)
259 bool bReturn = false;
262 SciErr sciErr = getVarType(pvApiCtx, _piVar, &iType);
265 printError(&sciErr, 0);
273 bReturn = export_double(_iH5File, _piVar, _pstName);
278 bReturn = export_poly(_iH5File, _piVar, _pstName);
283 bReturn = export_boolean(_iH5File, _piVar, _pstName);
288 bReturn = export_sparse(_iH5File, _piVar, _pstName);
291 case sci_boolean_sparse :
293 bReturn = export_boolean_sparse(_iH5File, _piVar, _pstName);
296 case sci_matlab_sparse :
298 bReturn = export_matlab_sparse(_piVar, _pstName);
303 bReturn = export_ints(_iH5File, _piVar, _pstName);
308 bReturn = export_handles(_piVar, _pstName);
313 bReturn = export_strings(_iH5File, _piVar, _pstName);
316 case sci_u_function :
318 bReturn = export_u_function(_piVar, _pstName);
321 case sci_c_function :
323 bReturn = export_c_function(_piVar, _pstName);
328 bReturn = export_lib(_piVar, _pstName);
335 bReturn = export_list(_iH5File, _piVar, _pstName, iType);
338 case sci_lufact_pointer :
340 bReturn = export_lufact_pointer(_piVar, _pstName);
343 case 0 : //void case to "null" items in list
345 bReturn = export_void(_iH5File, _piVar, _pstName);
358 static bool export_void(int _iH5File, int *_piVar, char* _pstName)
360 int iRet = writeVoid(_iH5File, _pstName);
366 char pstMsg[] = "void";
371 static bool export_undefined(int _iH5File, int *_piVar, char* _pstName)
373 int iRet = writeUndefined(_iH5File, _pstName);
379 char pstMsg[] = "void";
384 static bool export_list(int _iH5File, int *_piVar, char* _pstName, int _iVarType)
387 bool bReturn = false;
389 SciErr sciErr = getListItemNumber(pvApiCtx, _piVar, &iItemNumber);
392 printError(&sciErr, 0);
398 char* pstGroupName = createGroupName(_pstName);
401 sprintf(pstMsg, "list (%d)", iItemNumber);
406 void *pvList = openList(_iH5File, pstGroupName, iItemNumber);
407 for (int i = 0 ; i < iItemNumber ; i++)
409 int *piNewVar = NULL;
410 getListItemAddress(pvApiCtx, _piVar, i + 1, &piNewVar);//1 indexed
411 char* pstPathName = createPathName(pstGroupName, i);
413 if (piNewVar == NULL)
416 bReturn = export_undefined(_iH5File, piNewVar, pstPathName);
420 bReturn = export_data(_iH5File, piNewVar, pstPathName);
423 iRet = addItemInList(_iH5File, pvList, i, pstPathName);
425 if (bReturn == false || iRet)
429 closeList(_iH5File, pvList, _pstName, iItemNumber, _iVarType);
435 static bool export_double(int _iH5File, int *_piVar, char* _pstName)
438 int iComplex = isVarComplex(pvApiCtx, _piVar);
442 double *pdblReal = NULL;
443 double *pdblImg = NULL;
445 SciErr sciErr = getVarType(pvApiCtx, _piVar, &iType);
448 printError(&sciErr, 0);
452 if (iType != sci_matrix)
459 sciErr = getComplexMatrixOfDouble(pvApiCtx, _piVar, &iRows, &iCols, &pdblReal, &pdblImg);
462 printError(&sciErr, 0);
466 iRet = writeDoubleComplexMatrix(_iH5File, _pstName, iRows, iCols, pdblReal, pdblImg);
470 sciErr = getMatrixOfDouble(pvApiCtx, _piVar, &iRows, &iCols, &pdblReal);
473 printError(&sciErr, 0);
477 iRet = writeDoubleMatrix(_iH5File, _pstName, iRows, iCols, pdblReal);
486 sprintf(pstMsg, "double (%d x %d)", iRows, iCols);
491 static bool export_poly(int _iH5File, int *_piVar, char* _pstName)
496 int* piNbCoef = NULL;
497 double** pdblReal = NULL;
498 double** pdblImg = NULL;
499 char pstVarName[64] = {0};
502 SciErr sciErr = getPolyVariableName(pvApiCtx, _piVar, pstVarName, &iVarNameLen);
505 printError(&sciErr, 0);
509 if (isVarComplex(pvApiCtx, _piVar))
511 sciErr = getComplexMatrixOfPoly(pvApiCtx, _piVar, &iRows, &iCols, NULL, NULL, NULL);
514 printError(&sciErr, 0);
518 piNbCoef = (int*)MALLOC(iRows * iCols * sizeof(int));
519 sciErr = getComplexMatrixOfPoly(pvApiCtx, _piVar, &iRows, &iCols, piNbCoef, NULL, NULL);
522 printError(&sciErr, 0);
526 pdblReal = (double**)MALLOC(sizeof(double*) * iRows * iCols);
527 pdblImg = (double**)MALLOC(sizeof(double*) * iRows * iCols);
528 for (int i = 0 ; i < iRows * iCols ; i++)
530 pdblReal[i] = (double*)MALLOC(sizeof(double) * piNbCoef[i]);// for null termination
531 pdblImg[i] = (double*)MALLOC(sizeof(double) * piNbCoef[i]);// for null termination
533 sciErr = getComplexMatrixOfPoly(pvApiCtx, _piVar, &iRows, &iCols, piNbCoef, pdblReal, pdblImg);
536 printError(&sciErr, 0);
540 iRet = writePolyComplexMatrix(_iH5File, _pstName, pstVarName, iRows, iCols, piNbCoef, pdblReal, pdblImg);
544 sciErr = getMatrixOfPoly(pvApiCtx, _piVar, &iRows, &iCols, NULL, NULL);
547 printError(&sciErr, 0);
551 piNbCoef = (int*)MALLOC(iRows * iCols * sizeof(int));
552 sciErr = getMatrixOfPoly(pvApiCtx, _piVar, &iRows, &iCols, piNbCoef, NULL);
555 printError(&sciErr, 0);
559 pdblReal = (double**)MALLOC(sizeof(double*) * iRows * iCols);
560 for (int i = 0 ; i < iRows * iCols ; i++)
562 pdblReal[i] = (double*)MALLOC(sizeof(double) * piNbCoef[i]);// for null termination
564 sciErr = getMatrixOfPoly(pvApiCtx, _piVar, &iRows, &iCols, piNbCoef, pdblReal);
567 printError(&sciErr, 0);
571 iRet = writePolyMatrix(_iH5File, _pstName, pstVarName, iRows, iCols, piNbCoef, pdblReal);
580 sprintf(pstMsg, "poly (%d x %d)", iRows, iCols);
585 for (int i = 0 ; i < iRows * iCols ; i++)
594 for (int i = 0 ; i < iRows * iCols ; i++)
605 static bool export_boolean(int _iH5File, int *_piVar, char* _pstName)
611 //for error management
612 SciErr sciErr = getMatrixOfBoolean(pvApiCtx, _piVar, &iRows, &iCols, &piData);
615 printError(&sciErr, 0);
619 int iRet = writeBooleanMatrix(_iH5File, _pstName, iRows, iCols, piData);
627 sprintf(pstMsg, "bool (%d x %d)", iRows, iCols);
632 static bool export_boolean_sparse(int _iH5File, int *_piVar, char* _pstName)
638 int* piNbItemRow = NULL;
639 int* piColPos = NULL;
641 SciErr sciErr = getBooleanSparseMatrix(pvApiCtx, _piVar, &iRows, &iCols, &iNbItem, &piNbItemRow, &piColPos);
644 printError(&sciErr, 0);
648 iRet = writeBooleanSparseMatrix(_iH5File, _pstName, iRows, iCols, iNbItem, piNbItemRow, piColPos);
656 sprintf(pstMsg, "boolean sparse (%d x %d)", iRows, iCols);
661 static bool export_sparse(int _iH5File, int *_piVar, char* _pstName)
667 int* piNbItemRow = NULL;
668 int* piColPos = NULL;
669 double* pdblReal = NULL;
670 double* pdblImg = NULL;
673 if (isVarComplex(pvApiCtx, _piVar))
675 sciErr = getComplexSparseMatrix(pvApiCtx, _piVar, &iRows, &iCols, &iNbItem, &piNbItemRow, &piColPos, &pdblReal, &pdblImg);
678 printError(&sciErr, 0);
682 iRet = writeSparseComplexMatrix(_iH5File, _pstName, iRows, iCols, iNbItem, piNbItemRow, piColPos, pdblReal, pdblImg);
686 sciErr = getSparseMatrix(pvApiCtx, _piVar, &iRows, &iCols, &iNbItem, &piNbItemRow, &piColPos, &pdblReal);
689 printError(&sciErr, 0);
693 iRet = writeSparseMatrix(_iH5File, _pstName, iRows, iCols, iNbItem, piNbItemRow, piColPos, pdblReal);
702 sprintf(pstMsg, "sparse (%d x %d)", iRows, iCols);
707 static bool export_matlab_sparse(int *_piVar, char* _pstName)
709 print_type(_pstName);
713 static bool export_ints(int _iH5File, int *_piVar, char* _pstName)
721 SciErr sciErr = getMatrixOfIntegerPrecision(pvApiCtx, _piVar, &iPrec);
724 printError(&sciErr, 0);
731 sciErr = getMatrixOfInteger8(pvApiCtx, _piVar, &iRows, &iCols, (char**)&piData);
734 printError(&sciErr, 0);
737 iRet = writeInteger8Matrix(_iH5File, _pstName, iRows, iCols, (char*)piData);
740 sciErr = getMatrixOfUnsignedInteger8(pvApiCtx, _piVar, &iRows, &iCols, (unsigned char**)&piData);
743 printError(&sciErr, 0);
746 iRet = writeUnsignedInteger8Matrix(_iH5File, _pstName, iRows, iCols, (unsigned char*)piData);
749 sciErr = getMatrixOfInteger16(pvApiCtx, _piVar, &iRows, &iCols, (short**)&piData);
752 printError(&sciErr, 0);
755 iRet = writeInteger16Matrix(_iH5File, _pstName, iRows, iCols, (short*)piData);
758 sciErr = getMatrixOfUnsignedInteger16(pvApiCtx, _piVar, &iRows, &iCols, (unsigned short**)&piData);
761 printError(&sciErr, 0);
764 iRet = writeUnsignedInteger16Matrix(_iH5File, _pstName, iRows, iCols, (unsigned short*)piData);
767 sciErr = getMatrixOfInteger32(pvApiCtx, _piVar, &iRows, &iCols, (int**)&piData);
770 printError(&sciErr, 0);
773 iRet = writeInteger32Matrix(_iH5File, _pstName, iRows, iCols, (int*)piData);
776 sciErr = getMatrixOfUnsignedInteger32(pvApiCtx, _piVar, &iRows, &iCols, (unsigned int**)&piData);
779 printError(&sciErr, 0);
782 iRet = writeUnsignedInteger32Matrix(_iH5File, _pstName, iRows, iCols, (unsigned int*)piData);
785 //sciErr = getMatrixOfInteger64(_piVar, &iRows, &iCols, (long long**)&piData);
788 // printError(&sciErr, 0);
791 //iRet = writeInteger64Matrix(_iH5File, _pstName, iRows, iCols, (long long*)piData);
794 //sciErr = getMatrixOfUnsignedInteger64(_piVar, &iRows, &iCols, (unsigned long long**)&piData);
797 // printError(&sciErr, 0);
800 //iRet = writeUnsignedInteger64Matrix(_iH5File, _pstName, iRows, iCols, (unsigned long long*)piData);
813 sprintf(pstMsg, "int%d (%d x %d)", 8 * iPrec, iRows, iCols);
818 static bool export_handles(int *_piVar, char* _pstName)
820 print_type(_pstName);
824 static bool export_strings(int _iH5File, int *_piVar, char* _pstName)
830 char** pstData = NULL;
833 SciErr sciErr = getMatrixOfString(pvApiCtx, _piVar, &iRows, &iCols, NULL, NULL);
836 printError(&sciErr, 0);
840 piLen = (int*)MALLOC(iRows * iCols * sizeof(int));
841 sciErr = getMatrixOfString(pvApiCtx, _piVar, &iRows, &iCols, piLen, NULL);
844 printError(&sciErr, 0);
848 pstData = (char**)MALLOC(sizeof(char*) * iRows * iCols);
849 for (int i = 0 ; i < iRows * iCols ; i++)
851 pstData[i] = (char*)MALLOC(sizeof(char) * (piLen[i] + 1));// for null termination
853 sciErr = getMatrixOfString(pvApiCtx, _piVar, &iRows, &iCols, piLen, pstData);
856 printError(&sciErr, 0);
860 iRet = writeStringMatrix(_iH5File, _pstName, iRows, iCols, pstData);
868 sprintf(pstMsg, "string (%d x %d)", iRows, iCols);
871 freeArrayOfString(pstData, iRows * iCols);
875 static bool export_u_function(int *_piVar, char* _pstName)
877 print_type(_pstName);
881 static bool export_c_function(int *_piVar, char* _pstName)
883 print_type(_pstName);
887 static bool export_lib(int *_piVar, char* _pstName)
889 print_type(_pstName);
893 static bool export_lufact_pointer(int *_piVar, char* _pstName)
895 print_type(_pstName);
899 void print_type(char* _pstType)
902 for (int i = 0 ; i < iLevel ; i++)
906 sciprint("%s\n", _pstType);
910 int extractVarNameList(int _iStart, int _iEnd, char** _pstNameList)
914 for (int i = _iStart ; i <= _iEnd ; i++)
919 SciErr sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddr);
922 printError(&sciErr, 0);
926 if (getAllocatedSingleString(pvApiCtx, piAddr, &_pstNameList[iCount]))
928 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "export_to_hdf5", i);
937 /*--------------------------------------------------------------------------*/