* Port to matio 1.5.0 * Code cleaning * Prepare code for Scilab 6 (YaSp branch merge)
[scilab.git] / scilab / modules / matio / sci_gateway / c / sci_matfile_varreadnext.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Vincent COUVERT
4  * Copyright (C) 2010 - DIGITEO - Yann COLLETTE
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13 #include "api_scilab.h"
14 #include "gw_matio.h"
15
16 #include "CreateMatlabVariable.h"
17 #include "MALLOC.h"
18 #include "localization.h"
19 #include "Scierror.h"
20 #include "sciprint.h"
21
22 enum matfile_errors
23 {
24     NO_MORE_VARIABLES = -1,
25     UNKNOWN_VARIABLE_TYPE = 0
26 };
27
28 int sci_matfile_varreadnext(char *fname, unsigned long fname_len)
29 {
30     mat_t *matfile = NULL;
31     matvar_t *matvar = NULL;
32     int fileIndex = 0;
33     int returnedClass = 0, var_type;
34     int * fd_addr = NULL;
35     double tmp_dbl;
36     SciErr sciErr;
37
38     CheckRhs(1, 1);
39     CheckLhs(1, 3);
40
41     /* Input argument is the index of the file to read */
42
43     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &fd_addr);
44     if (sciErr.iErr)
45     {
46         printError(&sciErr, 0);
47         return 0;
48     }
49     sciErr = getVarType(pvApiCtx, fd_addr, &var_type);
50     if (sciErr.iErr)
51     {
52         printError(&sciErr, 0);
53         return 0;
54     }
55
56     if (var_type == sci_matrix)
57     {
58         getScalarDouble(pvApiCtx, fd_addr, &tmp_dbl);
59         if (!isScalar(pvApiCtx, fd_addr))
60         {
61             Scierror(999, _("%s: Wrong size for first input argument: Single double expected.\n"), fname);
62             return FALSE;
63         }
64         fileIndex = (int)tmp_dbl;
65     }
66     else
67     {
68         Scierror(999, _("%s: Wrong type for first input argument: Double expected.\n"), fname);
69         return FALSE;
70     }
71
72     /* Gets the corresponding matfile */
73     matfile_manager(MATFILEMANAGER_GETFILE, &fileIndex, &matfile);
74
75     if (matfile == NULL)
76     {
77         Scierror(999, _("%s: Invalid file identifier.\n"), fname);
78         return FALSE;
79     }
80
81     matvar = Mat_VarReadNext(matfile);
82     if ((matvar == NULL) || (matvar->name == NULL))
83     {
84         /* Return empty name */
85         createSingleString(pvApiCtx, Rhs + 1, "\0");
86         LhsVar(1) = Rhs + 1;
87
88         if (Lhs >= 2)
89         {
90             /* Return empty value */
91             createEmptyMatrix(pvApiCtx, Rhs + 2);
92             LhsVar(2) = Rhs + 2;
93         }
94
95         if (Lhs == 3)
96         {
97             /* Return error flag instead of variable class */
98             createScalarDouble(pvApiCtx, Rhs + 3, NO_MORE_VARIABLES);
99             LhsVar(3) = Rhs + 3;
100         }
101
102         PutLhsVar();
103
104         return TRUE;
105     }
106
107     /* To be sure isComplex is 0 or 1 */
108     matvar->isComplex =  matvar->isComplex != 0;
109
110     /* Return the variable name */
111     createSingleString(pvApiCtx, Rhs + 1, matvar->name);
112     LhsVar(1) = Rhs + 1;
113
114     returnedClass = matvar->class_type;
115
116     if (Lhs >= 2)
117     {
118         /* Return the values */
119         if (!CreateMatlabVariable(pvApiCtx, Rhs + 2, matvar, NULL, -1)) /* Could not Create Variable */
120         {
121             sciprint("Do not know how to read a variable of class %d.\n", matvar->class_type);
122             returnedClass = UNKNOWN_VARIABLE_TYPE;
123         }
124         LhsVar(2) = Rhs + 2;
125     }
126
127     if (Lhs == 3)
128     {
129         /* Create class return value */
130         createScalarDouble(pvApiCtx, Rhs + 3, returnedClass);
131         LhsVar(3) = Rhs + 3;
132     }
133
134     Mat_VarFree(matvar);
135     PutLhsVar();
136     return TRUE;
137 }