* Port to matio 1.5.0 * Code cleaning * Prepare code for Scilab 6 (YaSp branch merge)
[scilab.git] / scilab / modules / matio / src / c / GetCharVariable.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  * Copyright (C) 2010 - DIGITEO - Vincent COUVERT
6  *
7  * This file must be used under the terms of the CeCILL.
8  * This source file is licensed as described in the file COPYING, which
9  * you should have received as part of this distribution.  The terms
10  * are also available at
11  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
12  *
13  */
14 #include <string.h>
15 #include "GetMatlabVariable.h"
16 #include "api_scilab.h"
17 #include "sci_types.h"
18 #include "freeArrayOfString.h"
19 #ifdef _MSC_VER
20 #include "strdup_windows.h"
21 #endif
22 #include "MALLOC.h"
23 #include "localization.h"
24
25 matvar_t *GetCharVariable(void *pvApiCtx, int iVar, const char *name, int * parent, int item_position)
26 {
27     int rank = 0, i = 0, j = 0;
28     size_t *pszDims = NULL;
29     int *piDims = NULL;
30     matvar_t *createdVar = NULL;
31     int* piLen = NULL;
32     char** pstData = NULL;
33     char* pstMatData = NULL;
34     int * piAddr = NULL;
35     int * item_addr = NULL;
36     int var_type;
37     int saveDim = 0; /* Used to save old dimension before restoring it */
38     SciErr sciErr;
39
40     if (parent == NULL)
41     {
42         sciErr = getVarAddressFromPosition(pvApiCtx, iVar, &piAddr);
43         if (sciErr.iErr)
44         {
45             printError(&sciErr, 0);
46             return NULL;
47         }
48         sciErr = getVarType(pvApiCtx, piAddr, &var_type);
49         if (sciErr.iErr)
50         {
51             printError(&sciErr, 0);
52             return NULL;
53         }
54     }
55     else
56     {
57         sciErr = getListItemAddress(pvApiCtx, parent, item_position, &item_addr);
58         if (sciErr.iErr)
59         {
60             printError(&sciErr, 0);
61             return NULL;
62         }
63         sciErr = getVarType(pvApiCtx, item_addr, &var_type);
64         if (sciErr.iErr)
65         {
66             printError(&sciErr, 0);
67             return NULL;
68         }
69     }
70
71     if (var_type == sci_strings) /* 2-D array */
72     {
73         rank = 2;
74         piDims = (int*)MALLOC(sizeof(int) * rank);
75         if (piDims == NULL)
76         {
77             Scierror(999, _("%s: No more memory.\n"), "GetCharVariable");
78             return NULL;
79         }
80
81         if (parent == NULL)
82         {
83             // First call to retrieve dimensions
84             sciErr = getMatrixOfString(pvApiCtx, piAddr, &piDims[0], &piDims[1], NULL, NULL);
85             if (sciErr.iErr)
86             {
87                 printError(&sciErr, 0);
88                 return 0;
89             }
90             piLen = (int *)MALLOC(piDims[0] * piDims[1] * sizeof(int));
91             // Second call to retrieve length of each string
92             sciErr = getMatrixOfString(pvApiCtx, piAddr, &piDims[0], &piDims[1], piLen, NULL);
93             if (sciErr.iErr)
94             {
95                 printError(&sciErr, 0);
96                 return 0;
97             }
98             pstData = (char**)MALLOC(sizeof(char*) * piDims[0] * piDims[1]);
99             for (i = 0 ; i < piDims[0] * piDims[1] ; i++)
100             {
101                 pstData[i] = (char*)MALLOC(sizeof(char) * (piLen[i] + 1)); //+ 1 for null termination
102             }
103             // Third call to retrieve data
104             sciErr = getMatrixOfString(pvApiCtx, piAddr, &piDims[0], &piDims[1], piLen, pstData);
105             if (sciErr.iErr)
106             {
107                 printError(&sciErr, 0);
108                 return 0;
109             }
110         }
111         else
112         {
113             // First call to retrieve dimensions
114             sciErr  = getMatrixOfStringInList(pvApiCtx, parent, item_position, &piDims[0], &piDims[1], NULL, NULL);
115             if (sciErr.iErr)
116             {
117                 printError(&sciErr, 0);
118                 return NULL;
119             }
120             piLen = (int *)MALLOC(piDims[0] * piDims[1] * sizeof(int));
121             // Second call to retrieve length of each string
122             sciErr = getMatrixOfStringInList(pvApiCtx, parent, item_position, &piDims[0], &piDims[1], piLen, NULL);
123             if (sciErr.iErr)
124             {
125                 printError(&sciErr, 0);
126                 return NULL;
127             }
128             pstData = (char**)MALLOC(sizeof(char*) * piDims[0] * piDims[1]);
129             for (i = 0 ; i < piDims[0] * piDims[1] ; i++)
130             {
131                 pstData[i] = (char*)MALLOC(sizeof(char) * (piLen[i] + 1)); //+ 1 for null termination
132             }
133             // Third call to retrieve data
134             sciErr = getMatrixOfStringInList(pvApiCtx, parent, item_position, &piDims[0], &piDims[1], piLen, pstData);
135             if (sciErr.iErr)
136             {
137                 printError(&sciErr, 0);
138                 return NULL;
139             }
140         }
141
142         pszDims = (size_t*) MALLOC(rank * sizeof(size_t));
143         if (pszDims == NULL)
144         {
145             Scierror(999, _("%s: No more memory.\n"), "GetCharVariable");
146             return NULL;
147         }
148         for (i = 0; i < rank; i++)
149         {
150             pszDims[i] = piDims[i];
151         }
152
153         if (piDims[0] == 0) /* Empty character string */
154         {
155             createdVar = Mat_VarCreate(name, MAT_C_CHAR, MAT_T_UINT8, rank, pszDims, pstData[0], 0);
156         }
157         else if (piDims[0]*piDims[1] == 1) /* Scalar character string */
158         {
159             saveDim = piDims[1];
160             pszDims[1] = piLen[0];
161             createdVar = Mat_VarCreate(name, MAT_C_CHAR, MAT_T_UINT8, rank, pszDims, pstData[0], 0);
162             pszDims[1] = saveDim;
163         }
164         else /* More than one character string -> save as a Cell */
165         {
166             if (piDims[0] == 1)
167             {
168                 /* TODO: Should be saved as a cell */
169                 Scierror(999, _("%s: Row array of strings saving is not implemented.\n"), "GetCharVariable");
170                 freeArrayOfString(pstData, piDims[0]*piDims[1]);
171                 FREE(pszDims);
172                 FREE(piDims);
173                 FREE(piLen);
174                 return NULL;
175             }
176             else if (piDims[1] == 1)
177             {
178                 /* Check that all strings have the same length */
179                 for (i = 0 ; i < piDims[0] ; i++)
180                 {
181                     if (piLen[0] != piLen[i])
182                     {
183                         /* TODO: Should be saved as a cell */
184                         Scierror(999, _("%s: Column array of strings with different lengths saving is not implemented.\n"), "GetCharVariable");
185                         freeArrayOfString(pstData, piDims[0]*piDims[1]);
186                         FREE(pszDims);
187                         FREE(piDims);
188                         FREE(piLen);
189                         return NULL;
190                     }
191                 }
192
193                 /* Reorder characters */
194                 pstMatData = (char*)MALLOC(sizeof(char) * piDims[0] * piLen[0]);
195                 for (i = 0 ; i < piDims[0] ; i++)
196                 {
197                     for (j = 0 ; j < piLen[0] ; j++)
198                     {
199                         pstMatData[i + j * piDims[0]] = pstData[i][j];
200                     }
201                 }
202
203                 /* Save the variable */
204                 saveDim = piDims[1];
205                 pszDims[1] = piLen[0];
206                 createdVar = Mat_VarCreate(name, MAT_C_CHAR, MAT_T_UINT8, rank, pszDims, pstMatData, 0);
207                 pszDims[1] = saveDim;
208
209                 freeArrayOfString(pstData, piDims[0]*piDims[1]); /* FREE now because dimensions are changed just below */
210                 FREE(pstMatData);
211                 FREE(pszDims);
212                 FREE(piDims);
213                 FREE(piLen);
214             }
215             else
216             {
217                 /* TODO: Should be saved as a cell */
218                 Scierror(999, _("%s: 2D array of strings saving is not implemented.\n"), "GetCharVariable");
219                 freeArrayOfString(pstData, piDims[0]*piDims[1]);
220                 FREE(pszDims);
221                 FREE(piDims);
222                 FREE(piLen);
223                 return NULL;
224             }
225         }
226     }
227     else
228     {
229         Scierror(999, _("%s: Wrong type for first input argument: String matrix expected.\n"), "GetCharVariable");
230         freeArrayOfString(pstData, piDims[0]*piDims[1]);
231         FREE(pszDims);
232         FREE(piDims);
233         FREE(piLen);
234         return NULL;
235     }
236
237     return createdVar;
238 }