diff --git a/src/mat.c b/src/mat.c index a74c1037..2a53c180 100644 --- a/src/mat.c +++ b/src/mat.c @@ -783,7 +783,7 @@ Mat_GetDir(mat_t *mat, size_t *n) } mat->next_index = 0; while ( mat->next_index < mat->num_datasets ) { - matvar = Mat_VarReadNextInfo(mat); + matvar = Mat_VarReadNextInfo73(mat, NULL, NULL, 1); if ( NULL != matvar ) { if ( NULL != matvar->name ) { mat->dir[i++] = strdup(matvar->name); @@ -2587,7 +2587,7 @@ Mat_VarReadDataLinear(mat_t *mat, matvar_t *matvar, void *data, int start, int s /** @brief Reads the information of the next variable in a MAT file * * Reads the next variable's information (class,flags-complex/global/logical, - * rank,dimensions, name, etc) from the Matlab MAT file. After reading, the MAT + * rank,dimensions, name, etc) from the Matlab MAT file. After reading, the MAT * file is positioned past the current variable. * @ingroup MAT * @param mat Pointer to the MAT file @@ -2604,11 +2604,13 @@ Mat_VarReadNextInfo(mat_t *mat) * * Reads the next variable's information (class,flags-complex/global/logical, * rank,dimensions, name, etc) from the Matlab MAT file. Calls a user callback - * to check where the variable has to be fully read of skipped. + * to check where the variable has to be fully read or skipped. * If skipped tries to read next till accepted or EOF. * After reading, the MAT file is positioned past the current variable. * @ingroup MAT * @param mat Pointer to the MAT file + * @param pred User callback function + * @param user_data User data to be passed to the callback function * @return Pointer to the @ref matvar_t structure containing the MAT * variable information */ @@ -2625,7 +2627,7 @@ Mat_VarReadNextInfoPredicate(mat_t *mat, mat_iter_pred_t pred, const void *user_ break; case MAT_FT_MAT73: #if defined(MAT73) && MAT73 - matvar = Mat_VarReadNextInfo73(mat, pred, user_data); + matvar = Mat_VarReadNextInfo73(mat, pred, user_data, 0); #else matvar = NULL; #endif @@ -2644,8 +2646,8 @@ Mat_VarReadNextInfoPredicate(mat_t *mat, mat_iter_pred_t pred, const void *user_ static int Mat_IteratorNameAcceptor(const char *name, const void *user_data) { - const char *required_name = user_data; - return name && required_name && strcmp(name, required_name) == 0; + const char *required_name = (const char *)user_data; + return (NULL != name) && (NULL != required_name) && 0 == strcmp(name, required_name); } /** @brief Reads the information of a variable with the given name from a MAT file @@ -2816,8 +2818,8 @@ Mat_VarReadNextPredicate(mat_t *mat, mat_iter_pred_t pred, const void *user_data } break; } - } while ( pred && pred(matvar->name, user_data) == - 0 ); /* for 7.3 the predicate will be called one extra time */ + } while ( (NULL != pred) && 0 == pred(matvar->name, user_data) ); + /* for 7.3 the predicate will be called one extra time */ return matvar; } diff --git a/src/mat73.c b/src/mat73.c index f2682e07..72d985c5 100644 --- a/src/mat73.c +++ b/src/mat73.c @@ -56,6 +56,7 @@ struct ReadNextIterData matvar_t *matvar; mat_iter_pred_t pred; const void *pred_user_data; + int only_root_name; }; struct ReadGroupInfoIterData @@ -3157,16 +3158,19 @@ Mat_VarReadDataLinear73(mat_t *mat, matvar_t *matvar, void *data, int start, int * * @ingroup mat_internal * @param mat MAT file pointer + * @param pred User callback function + * @param user_data User data to be passed to the callback function + * @param only_root_name Flag to only iterate on root level * @return pointer to the MAT variable or NULL * @endif */ matvar_t * -Mat_VarReadNextInfo73(mat_t *mat, mat_iter_pred_t pred, const void *user_data) +Mat_VarReadNextInfo73(mat_t *mat, mat_iter_pred_t pred, const void *user_data, int only_root_name) { hid_t id; hsize_t idx; herr_t herr; - struct ReadNextIterData mat_data; + struct ReadNextIterData iter_data; if ( mat == NULL ) return NULL; @@ -3176,15 +3180,16 @@ Mat_VarReadNextInfo73(mat_t *mat, mat_iter_pred_t pred, const void *user_data) id = *(hid_t *)mat->fp; idx = (hsize_t)mat->next_index; - mat_data.mat = mat; - mat_data.matvar = NULL; - mat_data.pred = pred; - mat_data.pred_user_data = user_data; + iter_data.mat = mat; + iter_data.matvar = NULL; + iter_data.pred = pred; + iter_data.pred_user_data = user_data; + iter_data.only_root_name = only_root_name; herr = H5Literate(id, H5_INDEX_NAME, H5_ITER_NATIVE, &idx, Mat_VarReadNextInfoIterate, - (void *)&mat_data); + (void *)&iter_data); if ( herr > 0 ) mat->next_index = (size_t)idx; - return mat_data.matvar; + return iter_data.matvar; } static herr_t @@ -3192,17 +3197,17 @@ Mat_VarReadNextInfoIterate(hid_t id, const char *name, const H5L_info_t *info, v { mat_t *mat; H5O_INFO_T object_info; - struct ReadNextIterData *mat_data; + struct ReadNextIterData *iter_data; /* FIXME: follow symlinks, datatypes? */ - mat_data = (struct ReadNextIterData *)op_data; + iter_data = (struct ReadNextIterData *)op_data; /* Check that this is not the /#refs# or /"#subsystem#" group */ if ( 0 == strcmp(name, "#refs#") || 0 == strcmp(name, "#subsystem#") ) return 0; - if ( mat_data && mat_data->pred && - mat_data->pred(name, mat_data->pred_user_data) == 0 ) /* do we need to skip it? */ + if ( (NULL != iter_data) && (NULL != iter_data->pred) && + 0 == iter_data->pred(name, iter_data->pred_user_data) ) /* do we need to skip it? */ return 0; object_info.type = H5O_TYPE_UNKNOWN; @@ -3210,9 +3215,9 @@ Mat_VarReadNextInfoIterate(hid_t id, const char *name, const H5L_info_t *info, v if ( H5O_TYPE_DATASET != object_info.type && H5O_TYPE_GROUP != object_info.type ) return 0; - if ( NULL == mat_data ) + if ( NULL == iter_data ) return -1; - mat = mat_data->mat; + mat = iter_data->mat; switch ( object_info.type ) { case H5O_TYPE_DATASET: { @@ -3228,17 +3233,19 @@ Mat_VarReadNextInfoIterate(hid_t id, const char *name, const H5L_info_t *info, v return -1; } - dset_id = H5Dopen(id, name, H5P_DEFAULT); - err = Mat_H5ReadDatasetInfo(mat, matvar, dset_id); - if ( matvar->internal->id != dset_id ) { - /* Close dataset and increment count */ - H5Dclose(dset_id); - } - if ( err ) { - Mat_VarFree(matvar); - return -1; + if ( !iter_data->only_root_name ) { + dset_id = H5Dopen(id, name, H5P_DEFAULT); + err = Mat_H5ReadDatasetInfo(mat, matvar, dset_id); + if ( matvar->internal->id != dset_id ) { + /* Close dataset and increment count */ + H5Dclose(dset_id); + } + if ( err ) { + Mat_VarFree(matvar); + return -1; + } } - mat_data->matvar = matvar; + iter_data->matvar = matvar; break; } case H5O_TYPE_GROUP: { @@ -3254,14 +3261,16 @@ Mat_VarReadNextInfoIterate(hid_t id, const char *name, const H5L_info_t *info, v return -1; } - dset_id = H5Gopen(id, name, H5P_DEFAULT); - err = Mat_H5ReadGroupInfo(mat, matvar, dset_id); - H5Gclose(dset_id); - if ( err ) { - Mat_VarFree(matvar); - return -1; + if ( !iter_data->only_root_name ) { + dset_id = H5Gopen(id, name, H5P_DEFAULT); + err = Mat_H5ReadGroupInfo(mat, matvar, dset_id); + H5Gclose(dset_id); + if ( err ) { + Mat_VarFree(matvar); + return -1; + } } - mat_data->matvar = matvar; + iter_data->matvar = matvar; break; } default: diff --git a/src/mat73.h b/src/mat73.h index d91a8f39..ada3d5da 100644 --- a/src/mat73.h +++ b/src/mat73.h @@ -41,7 +41,8 @@ EXTERN int Mat_VarReadData73(mat_t *mat, matvar_t *matvar, void *data, int *star int *edge); EXTERN int Mat_VarReadDataLinear73(mat_t *mat, matvar_t *matvar, void *data, int start, int stride, int edge); -EXTERN matvar_t *Mat_VarReadNextInfo73(mat_t *mat, mat_iter_pred_t pred, const void *user_data); +EXTERN matvar_t *Mat_VarReadNextInfo73(mat_t *mat, mat_iter_pred_t pred, const void *user_data, + int only_root_name); EXTERN int Mat_VarWrite73(mat_t *mat, matvar_t *matvar, int compress); EXTERN int Mat_VarWriteAppend73(mat_t *mat, matvar_t *matvar, int compress, int dim);