1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
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 #ifndef __INSERTION_HPP__
17 #define __INSERTION_HPP__
18 
19 #include "XMLRhsValue.hxx"
20 
21 extern "C"
22 {
23 #include <stdio.h>
24 #include "gw_xml.h"
25 #include "Scierror.h"
26 #include "api_scilab.h"
27 #include "xml_mlist.h"
28 #include "localization.h"
29 }
30 
31 using namespace org_modules_xml;
32 
33 /*--------------------------------------------------------------------------*/
34 #define __XML_CHECK_TYPE__(TYPEIN,REQUIREDTYPE,FIELD) if (typeid(TYPEIN) != typeid(REQUIREDTYPE)) \
35     {                                                                   \
36         Scierror(999, gettext("%s: Wrong type to set %s field.\n"), fname, FIELD); \
37         return false;                                                   \
38     }
39 /*--------------------------------------------------------------------------*/
40 
41 /**
42  * Sets the properties of a XMLDocument
43  * A value will have the type T
44  * @param fname function name
45  * @param doc the XMLDocument
46  * @param field te field name
47  * @param value the new value
48  */
49 template <class T>
setProperty(char * fname,org_modules_xml::XMLDocument & doc,const char * field,T & value)50 bool setProperty(char * fname, org_modules_xml::XMLDocument & doc, const char * field, T & value)
51 {
52     if (!strcmp("root", field))
53     {
54         if (typeid(T &) != typeid(XMLElement &) && typeid(T &) != typeid(std::string &))
55         {
56             Scierror(999, gettext("%s: Wrong type to set %s field.\n"), fname, "root");
57             return false;
58         }
59         if (typeid(T &) == typeid(XMLElement &))
60         {
61             doc.setRoot((XMLElement &)value);
62         }
63         else
64         {
65             std::string error;
66             doc.setRoot((std::string &)value, &error);
67             if (!error.empty())
68             {
69                 Scierror(999, gettext("%s: Not valid xml for root.\n"), fname);
70                 return false;
71             }
72         }
73     }
74     else if (!strcmp("url", field))
75     {
76         __XML_CHECK_TYPE__(T &, std::string &, "url");
77         doc.setDocumentURL((std::string &)value);
78     }
79     else
80     {
81         Scierror(999, gettext("%s: Unknown field: %s\n"), fname, field);
82         return false;
83     }
84 
85     return true;
86 }
87 /*--------------------------------------------------------------------------*/
88 
89 /**
90  * Sets the properties of a XMLElement
91  * A value will have the type T
92  * @param fname function name
93  * @param elem the XMLElement
94  * @param field te field name
95  * @param value the new value
96  */
97 template <class T>
setProperty(char * fname,XMLElement & elem,const char * field,T & value)98 bool setProperty(char * fname, XMLElement & elem, const char * field, T & value)
99 {
100     if (!strcmp("name", field))
101     {
102         __XML_CHECK_TYPE__(T &, std::string &, "name");
103         elem.setNodeName((std::string &)value);
104     }
105     else if (!strcmp("namespace", field))
106     {
107         __XML_CHECK_TYPE__(T &, XMLNs &, "namespace");
108         elem.setNodeNameSpace((XMLNs &)value);
109     }
110     else if (!strcmp("content", field))
111     {
112         __XML_CHECK_TYPE__(T &, std::string &, "content");
113         elem.setNodeContent((std::string &)value);
114     }
115     else if (!strcmp("type", field))
116     {
117         Scierror(999, gettext("%s: Field %s is not modifiable: %s\n"), fname, "type");
118         return false;
119     }
120     else if (!strcmp("parent", field))
121     {
122         Scierror(999, gettext("%s: Field %s is not modifiable: %s\n"), fname, "parent");
123         return false;
124     }
125     else if (!strcmp("attributes", field))
126     {
127         __XML_CHECK_TYPE__(T &, XMLAttr &, "attributes");
128         elem.setAttributes((XMLAttr &)value);
129     }
130     else if (!strcmp("children", field))
131     {
132         if (typeid(T &) != typeid(XMLElement &) && typeid(T &) != typeid(XMLNodeList &) && typeid(T &) != typeid(std::string &))
133         {
134             Scierror(999, gettext("%s: Wrong type to set %s field.\n"), fname, "children");
135             return false;
136         }
137         if (typeid(T &) == typeid(XMLElement &))
138         {
139             elem.setChildren((XMLElement &)value);
140         }
141         else if (typeid(T &) == typeid(XMLNodeList &))
142         {
143             elem.setChildren((XMLNodeList &)value);
144         }
145         else
146         {
147             elem.setChildren((std::string &)value);
148         }
149     }
150     else
151     {
152         Scierror(999, gettext("%s: Unknown field: %s\n"), fname, field);
153         return false;
154     }
155 
156     return true;
157 }
158 /*--------------------------------------------------------------------------*/
159 
160 /**
161  * Function to handle insertion in different XMLObjects
162  * @param fname the function name
163  * @param fname_len the function name length
164  */
165 template<class T, class U>
sci_insertion(char * fname,void * pvApiCtx)166 int sci_insertion(char * fname, void* pvApiCtx)
167 {
168     T * a;
169     U * b;
170     int lhsid;
171     SciErr err;
172     int * fieldaddr = 0;
173     int * rhsaddr = 0;
174     int * lhsaddr = 0;
175     char * field = 0;
176     bool success;
177 
178     CheckLhs(0, 1);
179     CheckRhs(3, 3);
180 
181     err = getVarAddressFromPosition(pvApiCtx, 1, &fieldaddr);
182     if (err.iErr)
183     {
184         printError(&err, 0);
185         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
186         return 0;
187     }
188 
189     if (!isStringType(pvApiCtx, fieldaddr))
190     {
191         Scierror(999, gettext("%s: Wrong type for input argument #%i: string expected.\n"), fname, 1);
192         return 0;
193     }
194 
195     err = getVarAddressFromPosition(pvApiCtx, 2, &rhsaddr);
196     if (err.iErr)
197     {
198         printError(&err, 0);
199         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
200         return 0;
201     }
202 
203     err = getVarAddressFromPosition(pvApiCtx, 3, &lhsaddr);
204     if (err.iErr)
205     {
206         printError(&err, 0);
207         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
208         return 0;
209     }
210 
211     if (getAllocatedSingleString(pvApiCtx, fieldaddr, &field) != 0)
212     {
213         Scierror(999, _("%s: No more memory.\n"), fname);
214         return 0;
215     }
216     lhsid = getXMLObjectId(lhsaddr, pvApiCtx);
217 
218     a = XMLObject::getFromId<T>(lhsid);
219     if (!a)
220     {
221         freeAllocatedSingleString(field);
222         Scierror(999, gettext("%s: XML object does not exist.\n"), fname);
223         return 0;
224     }
225 
226     success = XMLRhsValue::get(fname, rhsaddr, &b, pvApiCtx);
227     if (!success)
228     {
229         freeAllocatedSingleString(field);
230         Scierror(999, gettext("%s: Error in getting rhs argument.\n"), fname);
231         return 0;
232     }
233 
234     success = setProperty<U>(fname, *a, const_cast<char *>(field), *b);
235     freeAllocatedSingleString(field);
236 
237     if (typeid(U) == typeid(std::string))
238     {
239         delete b;
240     }
241 
242     if (a->createOnStack(Rhs + 1, pvApiCtx))
243     {
244         LhsVar(1) = Rhs + 1;
245     }
246     else
247     {
248         LhsVar(1) = 0;
249     }
250 
251     PutLhsVar();
252 
253     return 0;
254 }
255 
256 #endif
257