2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - 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
19 //#include <winbase.h>
26 #include "sci_types.h"
28 #include "h5_attributeConstants.h"
29 #include "h5_readDataFromFile.h"
30 #include "doublecomplex.h"
34 static herr_t find_attr_by_name(hid_t loc_id, const char *name, void *data)
36 return !strcmp(name, (const char *)data);
39 /************************************************************
41 Operator function. Prints the name and type of the object
44 ************************************************************/
45 static herr_t op_func(hid_t loc_id, const char *name, void *operator_data)
49 int *pDataSetId = (int*)operator_data;
52 * Get type of the object and return only datasetId
53 * through operator_data.
55 status = H5Gget_objinfo(loc_id, name, 0, &statbuf);
66 *pDataSetId = H5Dopen(loc_id, name);
77 static int readIntAttribute(int _iDatasetId, const char *_pstName)
83 if (H5Aiterate(_iDatasetId, NULL, find_attr_by_name, (void *)_pstName))
85 iAttributeId = H5Aopen_name(_iDatasetId, _pstName);
91 status = H5Aread(iAttributeId, H5T_NATIVE_INT, &iVal);
97 status = H5Aclose(iAttributeId);
107 ** WARNING : this function returns an allocated value that must be freed.
109 static char* readAttribute(int _iDatasetId, const char *_pstName)
112 hid_t iFileType, memtype, iSpace;
117 char *pstValue = NULL;
119 if (H5Aiterate(_iDatasetId, NULL, find_attr_by_name, (void *)_pstName))
121 iAttributeId = H5Aopen_name(_iDatasetId, _pstName);
122 if (iAttributeId < 0)
127 * Get the datatype and its size.
129 iFileType = H5Aget_type(iAttributeId);
130 iDim = H5Tget_size(iFileType);
131 iDim++; /* Make room for null terminator */
134 * Get dataspace and allocate memory for read buffer. This is a
135 * two dimensional attribute so the dynamic allocation must be done
138 iSpace = H5Aget_space(iAttributeId);
144 status = H5Sget_simple_extent_dims(iSpace, dims, NULL);
151 * Allocate space for string data.
153 pstValue = (char *)MALLOC((size_t) ((dims[0] * iDim + 1) * sizeof(char)));
156 * Create the memory datatype.
158 memtype = H5Tcopy(H5T_C_S1);
159 status = H5Tset_size(memtype, iDim);
169 status = H5Aread(iAttributeId, memtype, pstValue);
176 status = H5Tclose(memtype);
183 status = H5Sclose(iSpace);
190 status = H5Tclose(iFileType);
197 status = H5Aclose(iAttributeId);
208 static int checkAttribute(int _iDatasetId, char *_pstAttribute, char *_pstValue)
211 char *pstScilabClass = NULL;
213 //status = H5Giterate (_iFile, "/", NULL, op_func, &iDatasetId);
214 pstScilabClass = readAttribute(_iDatasetId, _pstAttribute);
215 if (pstScilabClass != NULL && strcmp(pstScilabClass, _pstValue) == 0)
221 FREE(pstScilabClass);
227 ** WARNING : this function returns an allocated value that must be freed.
229 char* getScilabVersionAttribute(int _iFile)
231 return readAttribute(_iFile, g_SCILAB_CLASS_SCI_VERSION);
234 int getSODFormatAttribute(int _iFile)
236 return readIntAttribute(_iFile, g_SCILAB_CLASS_SOD_VERSION);
239 int getDatasetInfo(int _iDatasetId, int* _iComplex, int* _iDims, int* _piDims)
243 H5T_class_t data_class;
244 hid_t space = H5Dget_space(_iDatasetId);
250 data_type = H5Dget_type(_iDatasetId);
251 data_class = H5Tget_class(data_type);
252 if (data_class == H5T_COMPOUND)
256 else if (data_class == H5T_REFERENCE)
258 *_iComplex = isComplexData(_iDatasetId);
265 *_iDims = H5Sget_simple_extent_ndims(space);
275 hsize_t* dims = (hsize_t*)MALLOC(sizeof(hsize_t) * *_iDims);
276 if (H5Sget_simple_extent_dims(space, dims, NULL) < 0)
283 for (i = 0 ; i < *_iDims ; i++)
285 //reverse dimensions to improve rendering in external tools
286 _piDims[i] = (int)dims[*_iDims - 1 - i];
296 int getSparseDimension(int _iDatasetId, int *_piRows, int *_piCols, int *_piNbItem)
301 //get number of item in the sparse matrix
302 getDatasetDims(_iDatasetId, _piRows, _piCols);
303 *_piNbItem = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ITEMS);
308 static int isEmptyDataset(int _iDatasetId)
310 return checkAttribute(_iDatasetId, (char *)g_SCILAB_CLASS_EMPTY, "true");
313 int isComplexData(int _iDatasetId)
315 return checkAttribute(_iDatasetId, (char *)g_SCILAB_CLASS_COMPLEX, "true");
318 int getDatasetPrecision(int _iDatasetId, int *_piPrec)
321 char *pstScilabClass = readAttribute(_iDatasetId, g_SCILAB_CLASS_PREC);
323 if (pstScilabClass == NULL)
327 else if (strcmp(pstScilabClass, "8") == 0)
331 else if (strcmp(pstScilabClass, "u8") == 0)
333 *_piPrec = SCI_UINT8;
335 else if (strcmp(pstScilabClass, "16") == 0)
337 *_piPrec = SCI_INT16;
339 else if (strcmp(pstScilabClass, "u16") == 0)
341 *_piPrec = SCI_UINT16;
343 else if (strcmp(pstScilabClass, "32") == 0)
345 *_piPrec = SCI_INT32;
347 else if (strcmp(pstScilabClass, "u32") == 0)
349 *_piPrec = SCI_UINT32;
351 else if (strcmp(pstScilabClass, "64") == 0)
353 *_piPrec = SCI_INT64;
355 else if (strcmp(pstScilabClass, "u64") == 0)
357 *_piPrec = SCI_UINT64;
364 FREE(pstScilabClass);
368 int getVariableNames(int _iFile, char **pstNameList)
375 status = H5Gget_num_objs(_iFile, &iCount);
381 for (i = 0; i < iCount; i++)
383 if (H5Gget_objtype_by_idx(_iFile, i) == H5G_DATASET)
385 if (pstNameList != NULL)
389 iLen = (int)H5Gget_objname_by_idx(_iFile, i, NULL, iLen);
390 pstNameList[iNbItem] = (char *)MALLOC(sizeof(char) * (iLen + 1)); //null terminated
391 H5Gget_objname_by_idx(_iFile, i, pstNameList[iNbItem], iLen + 1);
399 int getDataSetIdFromName(int _iFile, char *_pstName)
401 return H5Dopen(_iFile, _pstName);
404 void closeDataSet(int _id)
412 int getDataSetId(int _iFile)
420 status = H5Giterate(_iFile, "/", NULL, op_func, &iDatasetId);
429 int getListDims(int _iDatasetId, int *_piItems)
432 * Get dataspace and dimensions of the dataset. This is a
433 * two dimensional dataset.
435 if (isEmptyDataset(_iDatasetId))
441 *_piItems = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ITEMS);
446 int getDatasetDims(int _iDatasetId, int *_piRows, int *_piCols)
449 * Get dataspace and dimensions of the dataset. This is a
450 * two dimensional dataset.
452 if (isEmptyDataset(_iDatasetId))
459 *_piRows = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_ROWS);
460 *_piCols = readIntAttribute(_iDatasetId, g_SCILAB_CLASS_COLS);
465 int readDoubleMatrix(int _iDatasetId, double *_pdblData)
470 status = H5Dread(_iDatasetId, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pdblData);
476 status = H5Dclose(_iDatasetId);
485 int readDoubleComplexMatrix(int _iDatasetId, double *_pdblReal, double *_pdblImg)
493 doublecomplex* pData = NULL;
496 /*define compound dataset*/
497 compoundId = H5Tcreate(H5T_COMPOUND, sizeof(doublecomplex));
498 H5Tinsert(compoundId, "real", HOFFSET(doublecomplex, r), H5T_NATIVE_DOUBLE);
499 H5Tinsert(compoundId, "imag", HOFFSET(doublecomplex, i), H5T_NATIVE_DOUBLE);
501 //get dimension from dataset
502 getDatasetInfo(_iDatasetId, &iComplex, &iDims, NULL);
503 piDims = (int*)MALLOC(sizeof(int) * iDims);
504 iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, piDims);
508 pData = (doublecomplex*)MALLOC(sizeof(doublecomplex) * iSize);
510 status = H5Dread(_iDatasetId, compoundId, H5S_ALL, H5S_ALL, H5P_DEFAULT, pData);
518 vGetPointerFromDoubleComplex(pData, iSize, _pdblReal, _pdblImg);
520 status = H5Dclose(_iDatasetId);
529 int readEmptyMatrix(int _iDatasetId)
534 status = H5Dclose(_iDatasetId);
543 int readBooleanMatrix(int _iDatasetId, int *_piData)
550 status = H5Dread(_iDatasetId, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, _piData);
556 status = H5Dclose(_iDatasetId);
565 int readStringMatrix(int _iDatasetId, char **_pstData)
570 typeId = H5Tcopy(H5T_C_S1);
571 status = H5Tset_size(typeId, H5T_VARIABLE);
578 status = H5Dread(_iDatasetId, typeId, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pstData);
584 status = H5Tclose(typeId);
590 status = H5Dclose(_iDatasetId);
599 static int readComplexPoly(int _iDatasetId, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
604 //Get the datatype and its size.
606 iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, _piNbCoef);
608 //Allocate space for string data.
609 *_pdblReal = (double *)MALLOC(*_piNbCoef * sizeof(double));
610 *_pdblImg = (double *)MALLOC(*_piNbCoef * sizeof(double));
612 //Read the data and return result.
613 return readDoubleComplexMatrix(_iDatasetId, *_pdblReal, *_pdblImg);
616 static int readPoly(int _iDatasetId, int *_piNbCoef, double **_pdblData)
621 //Get the datatype and its size.
622 iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, _piNbCoef);
624 *_pdblData = (double *)MALLOC(*_piNbCoef * sizeof(double));
626 //Read the data and return result.
627 return readDoubleMatrix(_iDatasetId, *_pdblData);
630 int readCommonPolyMatrix(int _iDatasetId, char *_pstVarname, int _iComplex, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
634 char *pstVarName = 0;
635 hsize_t* piDims = NULL;
636 hobj_ref_t *pData = NULL;
640 for (i = 0 ; i < _iDims ; i++)
645 pData = (hobj_ref_t *) MALLOC(iSize * sizeof(hobj_ref_t));
650 status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pData);
657 for (i = 0; i < iSize; i++)
660 * Open the referenced object, get its name and type.
662 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pData[i]);
665 status = readComplexPoly(obj, &_piNbCoef[i], &_pdblReal[i], &_pdblImg[i]);
669 status = readPoly(obj, &_piNbCoef[i], &_pdblReal[i]);
679 pstVarName = readAttribute(_iDatasetId, g_SCILAB_CLASS_VARNAME);
680 strcpy(_pstVarname, pstVarName);
682 status = H5Dclose(_iDatasetId);
694 int readPolyMatrix(int _iDatasetId, char *_pstVarname, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblData)
696 return readCommonPolyMatrix(_iDatasetId, _pstVarname, 0, _iDims, _piDims, _piNbCoef, _pdblData, NULL);
699 int readPolyComplexMatrix(int _iDatasetId, char *_pstVarname, int _iDims, int* _piDims, int *_piNbCoef, double **_pdblReal, double **_pdblImg)
701 return readCommonPolyMatrix(_iDatasetId, _pstVarname, 1, _iDims, _piDims, _piNbCoef, _pdblReal, _pdblImg);
704 int readInteger8Matrix(int _iDatasetId, char *_pcData)
711 status = H5Dread(_iDatasetId, H5T_NATIVE_INT8, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pcData);
717 status = H5Dclose(_iDatasetId);
726 int readInteger16Matrix(int _iDatasetId, short *_psData)
733 status = H5Dread(_iDatasetId, H5T_NATIVE_INT16, H5S_ALL, H5S_ALL, H5P_DEFAULT, _psData);
739 status = H5Dclose(_iDatasetId);
748 int readInteger32Matrix(int _iDatasetId, int *_piData)
755 status = H5Dread(_iDatasetId, H5T_NATIVE_INT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, _piData);
761 status = H5Dclose(_iDatasetId);
770 int readInteger64Matrix(int _iDatasetId, long long *_pllData)
777 status = H5Dread(_iDatasetId, H5T_NATIVE_INT64, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pllData);
783 status = H5Dclose(_iDatasetId);
792 int readUnsignedInteger8Matrix(int _iDatasetId, unsigned char *_pucData)
799 status = H5Dread(_iDatasetId, H5T_NATIVE_UINT8, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pucData);
805 status = H5Dclose(_iDatasetId);
814 int readUnsignedInteger16Matrix(int _iDatasetId, unsigned short *_pusData)
821 status = H5Dread(_iDatasetId, H5T_NATIVE_UINT16, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pusData);
827 status = H5Dclose(_iDatasetId);
836 int readUnsignedInteger32Matrix(int _iDatasetId, unsigned int *_puiData)
843 status = H5Dread(_iDatasetId, H5T_NATIVE_UINT32, H5S_ALL, H5S_ALL, H5P_DEFAULT, _puiData);
849 status = H5Dclose(_iDatasetId);
858 int readUnsignedInteger64Matrix(int _iDatasetId, unsigned long long *_pullData)
865 status = H5Dread(_iDatasetId, H5T_NATIVE_UINT64, H5S_ALL, H5S_ALL, H5P_DEFAULT, _pullData);
871 status = H5Dclose(_iDatasetId);
880 int readCommonSparseComplexMatrix(int _iDatasetId, int _iComplex, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal, double *_pdblImg)
883 hobj_ref_t pRef[3] = {0};
889 status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pRef);
896 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[0]);
897 status = readInteger32Matrix(obj, _piNbItemRow);
904 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[1]);
905 status = readInteger32Matrix(obj, _piColPos);
912 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[2]);
916 status = readDoubleComplexMatrix(obj, _pdblReal, _pdblImg);
920 status = readDoubleMatrix(obj, _pdblReal);
931 int readSparseMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal)
933 return readCommonSparseComplexMatrix(_iDatasetId, 0, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, NULL);
936 int readSparseComplexMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos, double *_pdblReal, double *_pdblImg)
938 return readCommonSparseComplexMatrix(_iDatasetId, 1, _iRows, _iCols, _iNbItem, _piNbItemRow, _piColPos, _pdblReal, _pdblImg);
941 int readBooleanSparseMatrix(int _iDatasetId, int _iRows, int _iCols, int _iNbItem, int *_piNbItemRow, int *_piColPos)
944 hobj_ref_t pRef[2] = {0};
950 status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, pRef);
957 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[0]);
958 status = readInteger32Matrix(obj, _piNbItemRow);
967 obj = H5Rdereference(_iDatasetId, H5R_OBJECT, &pRef[1]);
968 status = readInteger32Matrix(obj, _piColPos);
977 int getScilabTypeFromDataSet(int _iDatasetId)
980 char *pstScilabClass = readAttribute(_iDatasetId, g_SCILAB_CLASS);
982 if (pstScilabClass == NULL)
986 /* HDF5 Float type + SCILAB_Class = double <=> double */
987 if (strcmp(pstScilabClass, g_SCILAB_CLASS_DOUBLE) == 0)
989 iVarType = sci_matrix;
991 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_STRING) == 0)
993 iVarType = sci_strings;
995 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BOOLEAN) == 0)
997 iVarType = sci_boolean;
999 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BOOLEAN) == 0)
1001 iVarType = sci_boolean;
1003 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_POLY) == 0)
1005 iVarType = sci_poly;
1007 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_INT) == 0)
1009 iVarType = sci_ints;
1011 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_SPARSE) == 0)
1013 iVarType = sci_sparse;
1015 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_BSPARSE) == 0)
1017 iVarType = sci_boolean_sparse;
1019 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_LIST) == 0)
1021 iVarType = sci_list;
1023 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_TLIST) == 0)
1025 iVarType = sci_tlist;
1027 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_MLIST) == 0)
1029 iVarType = sci_mlist;
1031 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_VOID) == 0)
1033 iVarType = sci_void;
1035 else if (strcmp(pstScilabClass, g_SCILAB_CLASS_UNDEFINED) == 0)
1037 iVarType = sci_undefined;
1040 FREE(pstScilabClass);
1044 int getListItemReferences(int _iDatasetId, hobj_ref_t ** _piItemRef)
1049 getListDims(_iDatasetId, &iItem);
1051 *_piItemRef = (hobj_ref_t *) MALLOC(iItem * sizeof(hobj_ref_t));
1053 status = H5Dread(_iDatasetId, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, *_piItemRef);
1062 int getListItemDataset(int _iDatasetId, void *_piItemRef, int _iItemPos, int *_piItemDataset)
1064 hobj_ref_t poRef = ((hobj_ref_t *) _piItemRef)[_iItemPos];
1066 *_piItemDataset = H5Rdereference(_iDatasetId, H5R_OBJECT, &poRef);
1068 if (*_piItemDataset == 0)
1076 int deleteListItemReferences(int _iDatasetId, void *_piItemRef)
1082 hobj_ref_t *poRef = (hobj_ref_t *) _piItemRef;
1087 status = H5Dclose(_iDatasetId);