f6dc231636205275f5222fb9c424942cf09ba760
[scilab.git] / scilab / modules / matio / src / c / CreateStructVariable.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
14 #ifdef _MSC_VER
15 #include "strdup_Windows.h"
16 #endif
17
18 #include "CreateMatlabVariable.h"
19 #include "freeArrayOfString.h"
20 #include "api_scilab.h"
21 #include "MALLOC.h"
22 #include "localization.h"
23 #include "Scierror.h"
24 #include "sciprint.h"
25
26 #define MATIO_ERROR if(_SciErr.iErr) \
27     {                                \
28       printError(&_SciErr, 0);       \
29       return 0;                      \
30     }
31
32 int CreateStructVariable(int iVar, matvar_t *matVariable, int * parent, int item_position)
33 {
34   char **fieldNames = NULL;
35   int nbFields = 0;
36   int fieldIndex = 0;
37   int K = 0;
38   int prodDims = 0;
39   int valueIndex = 0;
40   matvar_t *fieldMatVar = NULL;
41   matvar_t ** allData = NULL;
42   int * cell_addr = NULL;
43   int * cell_entry_addr = NULL;
44   int type;
45   SciErr _SciErr;
46     
47   /* Fields of the struct */
48   nbFields = 2; /* "st" "dims" */
49   nbFields += Mat_VarGetNumberOfFields(matVariable);
50
51   fieldNames = (char**) MALLOC(sizeof(char*) * nbFields);
52   if (fieldNames==NULL)
53     {
54       Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
55       return FALSE;
56     }
57   
58   fieldNames[0] = strdup("st");
59   if (fieldNames[0]==NULL)
60     {
61       Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
62       return FALSE;
63     }
64   fieldNames[1] = strdup("dims");
65   if (fieldNames[1]==NULL)
66     {
67       Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
68       return FALSE;
69     }
70   
71   for (fieldIndex = 1; fieldIndex < nbFields - 1; fieldIndex++)
72     {
73       fieldMatVar = Mat_VarGetStructField(matVariable, &fieldIndex, BY_INDEX, 0);
74       fieldNames[fieldIndex + 1] = strdup(fieldMatVar->name);
75       if (fieldNames[fieldIndex + 1]==NULL)
76         {
77           Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
78           return FALSE;
79         }
80     }
81   
82   /* Returned mlist initialization */
83   if (parent==NULL)
84     {
85       _SciErr = createMList(pvApiCtx, iVar, nbFields, &cell_addr); MATIO_ERROR;
86     }
87   else
88     {
89       _SciErr = createMListInList(pvApiCtx, iVar, parent, item_position, nbFields, &cell_addr); MATIO_ERROR;
90     }
91
92   /* FIRST LIST ENTRY: fieldnames */
93   _SciErr = createMatrixOfStringInList(pvApiCtx, iVar, cell_addr, 1, 1, nbFields, fieldNames); MATIO_ERROR;
94   
95   /* SECOND LIST ENTRY: Dimensions (int32 type) */
96   if (nbFields==2) /* Empty struct must have size 0x0 in Scilab */
97     {
98       matVariable->dims[0] = 0;
99       matVariable->dims[1] = 0;
100     }
101
102   if(matVariable->rank==2) /* Two dimensions */
103     {
104       _SciErr = createMatrixOfInteger32InList(pvApiCtx, iVar, cell_addr, 2, 1, matVariable->rank, matVariable->dims); MATIO_ERROR;
105     }
106   else /* 3 or more dimensions -> Scilab HyperMatrix */
107     {
108       type = I_INT32;
109       CreateHyperMatrixVariable(iVar, MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE, 
110                                 &type, &matVariable->rank, matVariable->dims, matVariable->data,
111                                 NULL, cell_addr, 2);
112     }
113
114   /* ALL OTHER ENTRIES: Fields data */
115   prodDims = 1;
116   for (K=0; K<matVariable->rank; K++)
117     {
118       prodDims *= matVariable->dims[K];
119     }
120
121   allData = (matvar_t**) (matVariable->data);
122
123   if (prodDims == 1) /* Scalar struct */
124     {
125       for (fieldIndex = 0; fieldIndex < nbFields - 2; fieldIndex++)
126         {
127           /* Create list entry in the stack */
128           if (!CreateMatlabVariable(iVar, allData[fieldIndex], cell_addr, fieldIndex+3)) /* Could not Create Variable */
129             {
130               if (allData[fieldIndex]->class_type != 0) /* class is 0 for not initialized fields */
131                 {
132                   sciprint("Do not know how to read a variable of class %d.\n", allData[fieldIndex]->class_type);
133                 }
134             }
135         }
136     }
137   else
138     {
139       for (fieldIndex = 0; fieldIndex < nbFields - 2; fieldIndex++)
140         {
141           _SciErr = createListInList(pvApiCtx, iVar, cell_addr, fieldIndex+3, prodDims, &cell_entry_addr); MATIO_ERROR;
142           
143           for (valueIndex = 0; valueIndex < prodDims; valueIndex++)
144             {
145               /* Create list entry in the stack */
146               if (!CreateMatlabVariable(iVar, allData[(fieldIndex) + (nbFields-2)*valueIndex], cell_entry_addr, valueIndex+1)) /* Could not Create Variable */
147                 {
148                   if (allData[(fieldIndex) + (nbFields-2)*valueIndex]->class_type != 0) /* class is 0 for not initialized fields */
149                     {
150                       sciprint("Do not know how to read a variable of class %d.\n", allData[(fieldIndex) + (nbFields-2)*valueIndex]->class_type);
151                     }
152                 }
153             }
154         }
155     }
156
157   freeArrayOfString(fieldNames, nbFields);
158
159   return TRUE;
160 }
161