Xcos: fix memleak on MVC objects after 238f0650
[scilab.git] / scilab / modules / scicos / sci_gateway / cpp / sci_sig2data.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Paul Bignier
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 #include <string>
17
18 #include "gw_scicos.hxx"
19
20 #include "types.hxx"
21 #include "internal.hxx"
22 #include "string.hxx"
23 #include "struct.hxx"
24 #include "function.hxx"
25
26 extern "C"
27 {
28 #include "localization.h"
29 #include "Scierror.h"
30 }
31
32 /*--------------------------------------------------------------------------*/
33 /* [x[,t]]=sig2data(B)
34 *
35 * Extract data from a 'scicos' signal structure.
36 *  x will be the field B.values
37 *  t will be the field B.time
38 *
39 * Usage :
40 * -->a(:,:,4)=([7 8 9;10 11 12]);
41 * -->b=data2sig(a,0.1)
42 * b  =
43 *   values: [2x3x4 hypermat]
44 *   time: [4x1 constant]
45 * -->b.time
46 * ans  =
47 *    0.
48 *    0.1.
49 *    0.2.
50 *    0.3.
51 *
52 * -->[x,t]=sig2data(b)
53 * t  =
54 *  0.
55 *   0.1
56 *   0.2
57 *   0.3
58 * x  =
59 * (:,:,1)
60 *
61 *  0.    0.    0.
62 *  0.    0.    0.
63 *
64 * Inputs
65 *   B    : a scilab structure that defines a signal :
66 *          B.values :  B data,
67 *          B.time   :  the samples time in the form of
68 *                      a columun vector.
69 *
70 * Outputs
71 *   x    : the field B.values
72 *   t    : the field B.time
73 *
74 * initial rev 08/11/07, Alan
75 *
76 */
77 /*--------------------------------------------------------------------------*/
78
79 static const std::string funname = "sig2data";
80
81 types::Function::ReturnValue sci_sig2data(types::typed_list &in, int _iRetCount, types::typed_list &out)
82 {
83     if (in.size() != 1)
84     {
85         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), funname.data(), 1);
86         return types::Function::Error;
87     }
88
89     if (_iRetCount > 2)
90     {
91         Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), funname.data(), 1, 2);
92         return types::Function::Error;
93     }
94
95     if (!in[0]->isStruct())
96     {
97         Scierror(999, _("%s: Wrong type for input argument #%d : A struct expected.\n"), funname.data(), 1);
98         return types::Function::Error;
99     }
100     types::Struct* B = in[0]->getAs<types::Struct>();
101
102     if (B->getSize() != 1)
103     {
104         Scierror(999, _("%s: Wrong size for input argument #%d : A single struct expected.\n"), funname.data(), 1);
105         return types::Function::Error;
106     }
107     auto fields = B->get(0)->getFields();
108     if (fields.size() != 2)
109     {
110         Scierror(999, _("%s: Wrong fields for input argument #%d : \"%s\" and \"%s\" expected.\n"), funname.data(), 1, "values", "time");
111         return types::Function::Error;
112     }
113     if (fields.find(L"values") == fields.end())
114     {
115         Scierror(999, _("%s: Wrong fields for input argument #%d : \"%s\" and \"%s\" expected.\n"), funname.data(), 1, "values", "time");
116         return types::Function::Error;
117     }
118     if (fields.find(L"time") == fields.end())
119     {
120         Scierror(999, _("%s: Wrong fields for input argument #%d : \"%s\" and \"%s\" expected.\n"), funname.data(), 1, "values", "time");
121         return types::Function::Error;
122     }
123
124     // Values
125     types::InternalType* A = B->get(0)->getData()[B->get(0)->getFieldIndex(L"values")];
126     types::InternalType* timeValues = B->get(0)->getData()[B->get(0)->getFieldIndex(L"time")];
127
128     out.push_back(A);
129     if (_iRetCount == 2)
130     {
131         out.push_back(timeValues);
132     }
133     return types::Function::OK;
134 }