Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for reading Matlab Objects from matfile V5 #64

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions src/inflate.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,55 @@ InflateVarNameTag(mat_t *mat, matvar_t *matvar, void *buf)
return bytesread;
}

/** @brief Inflates the variable name tag
*
* @ingroup mat_internal
* @param mat Pointer to the MAT file
* @param matvar Pointer to the MAT variable
* @param buf Pointer to store the variables name tag
* @return Number of bytes read from the file
*/
size_t
InflateClassNameTag(mat_t *mat, matvar_t *matvar, void *buf)
{
mat_uint8_t comp_buf[32];
size_t bytesread = 0, err;

if ( buf == NULL )
return 0;

if ( !matvar->internal->z->avail_in ) {
matvar->internal->z->avail_in = 1;
matvar->internal->z->next_in = comp_buf;
bytesread += fread(comp_buf, 1, 1, mat->fp);
}
matvar->internal->z->avail_out = 8;
matvar->internal->z->next_out = buf;
err = inflate(matvar->internal->z, Z_NO_FLUSH);
if ( err != Z_OK ) {
Mat_Critical("InflateClassNameTag: inflate returned %d", err);
return bytesread;
}
while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
matvar->internal->z->avail_in = 1;
matvar->internal->z->next_in = comp_buf;
bytesread += fread(comp_buf, 1, 1, mat->fp);
err = inflate(matvar->internal->z, Z_NO_FLUSH);
if ( err != Z_OK ) {
Mat_Critical("InflateVarNameTag: inflate returned %d", err);
return bytesread;
}
}

if ( matvar->internal->z->avail_in ) {
fseek(mat->fp, -(int)matvar->internal->z->avail_in, SEEK_CUR);
bytesread -= matvar->internal->z->avail_in;
matvar->internal->z->avail_in = 0;
}

return bytesread;
}

/** @brief Inflates the variable name
*
* @ingroup mat_internal
Expand Down Expand Up @@ -524,6 +573,55 @@ InflateVarName(mat_t *mat, matvar_t *matvar, void *buf, int N)

return bytesread;
}
/** @brief Inflates the class name
*
* @ingroup mat_internal
* @param mat Pointer to the MAT file
* @param matvar Pointer to the MAT variable
* @param buf Pointer to store the variables name
* @param N Number of characters in the name
* @return Number of bytes read from the file
*/
size_t
InflateClassName(mat_t *mat, matvar_t *matvar, void *buf, int N)
{
mat_uint8_t comp_buf[32];
size_t bytesread = 0, err;

if ( buf == NULL )
return 0;

if ( !matvar->internal->z->avail_in ) {
matvar->internal->z->avail_in = 1;
matvar->internal->z->next_in = comp_buf;
bytesread += fread(comp_buf, 1, 1, mat->fp);
}
matvar->internal->z->avail_out = N;
matvar->internal->z->next_out = buf;
err = inflate(matvar->internal->z, Z_NO_FLUSH);
if ( err != Z_OK ) {
Mat_Critical("InflateClassName: inflate returned %d", err);
return bytesread;
}
while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
matvar->internal->z->avail_in = 1;
matvar->internal->z->next_in = comp_buf;
bytesread += fread(comp_buf, 1, 1, mat->fp);
err = inflate(matvar->internal->z, Z_NO_FLUSH);
if ( err != Z_OK ) {
Mat_Critical("InflateClassName: inflate returned %d", err);
return bytesread;
}
}

if ( matvar->internal->z->avail_in ) {
fseek(mat->fp, -(int)matvar->internal->z->avail_in, SEEK_CUR);
bytesread -= matvar->internal->z->avail_in;
matvar->internal->z->avail_in = 0;
}

return bytesread;
}

/** @brief Inflates the data's tag
*
Expand Down
91 changes: 56 additions & 35 deletions src/mat.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,46 @@ Mat_PrintNumber(enum matio_types type, void *data)
}
}

/** @brief Copies a file
*
* @param src source file path
* @param dst destination file path
* @retval 0 on success
*/
static int
mat_copy(const char* src, const char* dst)
{
size_t len;
char buf[BUFSIZ] = {'\0'};
FILE* in;
FILE* out;

in = fopen(src, "rb");
if ( in == NULL ) {
Mat_Critical("Cannot open file \"%s\" for reading.", src);
return -1;
}

out = fopen(dst, "wb");
if ( out == NULL ) {
fclose(in);
Mat_Critical("Cannot open file \"%s\" for writing.", dst);
return -1;
}

while ( (len = fread(buf, sizeof(char), BUFSIZ, in)) > 0 ) {
if ( len != fwrite(buf, sizeof(char), len, out) ) {
fclose(in);
fclose(out);
Mat_Critical("Error writing to file \"%s\".", dst);
return -1;
}
}
fclose(in);
fclose(out);
return 0;
}

mat_complex_split_t *
ComplexMalloc(size_t nbytes)
{
Expand Down Expand Up @@ -680,6 +720,7 @@ Mat_VarCalloc(void)
matvar->internal->datapos = 0;
matvar->internal->num_fields = 0;
matvar->internal->fieldnames = NULL;
matvar->internal->classname = NULL;
#if defined(HAVE_ZLIB)
matvar->internal->z = NULL;
matvar->internal->data = NULL;
Expand Down Expand Up @@ -924,46 +965,26 @@ Mat_VarCreate(const char *name,enum matio_classes class_type,
return matvar;
}

/** @brief Copies a file
/** @brief Returns the class name of a object variable
*
* @param src source file path
* @param dst destination file path
* @retval 0 on success
* Returns the class name for the given object. The returned pointer is
* internal to the structure and should not be free'd.
* @ingroup MAT
* @param matvar Object matlab variable
* @returns classname
*/
static int
mat_copy(const char* src, const char* dst)
char *
Mat_VarGetObjectClassName(const matvar_t *matvar)
{
size_t len;
char buf[BUFSIZ] = {'\0'};
FILE* in;
FILE* out;

in = fopen(src, "rb");
if ( in == NULL ) {
Mat_Critical("Cannot open file \"%s\" for reading.", src);
return -1;
}

out = fopen(dst, "wb");
if ( out == NULL ) {
fclose(in);
Mat_Critical("Cannot open file \"%s\" for writing.", dst);
return -1;
}

while ( (len = fread(buf, sizeof(char), BUFSIZ, in)) > 0 ) {
if ( len != fwrite(buf, sizeof(char), len, out) ) {
fclose(in);
fclose(out);
Mat_Critical("Error writing to file \"%s\".", dst);
return -1;
}
if ( matvar == NULL || matvar->class_type != MAT_C_OBJECT ||
NULL == matvar->internal ) {
return NULL;
} else {
return matvar->internal->classname;
}
fclose(in);
fclose(out);
return 0;
}


/** @brief Deletes a variable from a file
*
* @ingroup MAT
Expand Down Expand Up @@ -1223,7 +1244,7 @@ Mat_VarDuplicate(const matvar_t *in, int opt)

if ( !opt ) {
out->data = in->data;
} else if ( (in->data != NULL) && (in->class_type == MAT_C_STRUCT) ) {
} else if ( (in->data != NULL) && ( ( in->class_type == MAT_C_STRUCT) || ( in->class_type == MAT_C_OBJECT ) ) ) {
out->data = malloc(in->nbytes);
if ( out->data != NULL && in->data_size > 0 ) {
int nfields = in->nbytes / in->data_size;
Expand Down
Loading