Split the examples of polyline properties + add a new image
[scilab.git] / scilab / modules / xml / src / cpp / extraction.hxx
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include <vector>
14
15 #include "XMLObject.hxx"
16 #include "XMLDocument.hxx"
17 #include "XMLElement.hxx"
18 #include "XMLNs.hxx"
19 #include "XMLAttr.hxx"
20 #include "XMLNodeList.hxx"
21
22 extern "C"
23 {
24 #include <string.h>
25 #include <stdio.h>
26 #include "gw_xml.h"
27 #include "Scierror.h"
28 #include "api_scilab.h"
29 #include "xml_mlist.h"
30 #include "xml_constants.h"
31 #include "localization.h"
32 #ifdef _MSC_VER
33 #include "strdup_windows.h"
34 #endif
35 }
36
37 using namespace org_modules_xml;
38
39 /*--------------------------------------------------------------------------*/
40
41 /**
42  * Creates a string on stack
43  * @param fname the function name
44  * @param str the string to put
45  * @param pos the stack position
46  * @return 1 if all is ok, else 0
47  */
48 int createStringOnStack(char * fname, const char * str, int pos, void* pvApiCtx)
49 {
50     SciErr err;
51
52     if (!str)
53     {
54         str = "";
55     }
56
57     if (strchr(str, '\n'))
58     {
59         char * tok = strdup(str);
60         char * stok = tok;
61         std::vector<char *> vector = std::vector<char *>();
62
63         tok = strtok(tok, "\n");
64         while (tok)
65         {
66             vector.push_back(tok);
67             tok = strtok(0, "\n");
68         }
69
70         if (vector.size())
71         {
72             err = createMatrixOfString(pvApiCtx, pos, (int)vector.size(), 1, const_cast<const char * const *>(&(vector[0])));
73         }
74         else
75         {
76             err = createMatrixOfDouble(pvApiCtx, pos, 0, 0, 0);
77         }
78
79         free(stok);
80     }
81     else
82     {
83         err = createMatrixOfString(pvApiCtx, pos, 1, 1, const_cast<const char * const *>(&str));
84     }
85
86     if (err.iErr)
87     {
88         printError(&err, 0);
89         return 0;
90     }
91
92     return 1;
93 }
94 /*--------------------------------------------------------------------------*/
95 /**
96  * Creates a new variable on stack according to the requested field
97  * @param fname the function name
98  * @param doc the document
99  * @param field the field name
100  * @param pos the stack position
101  * @return 1 if all is ok, else 0
102  */
103 int createVariableOnStack(char * fname, org_modules_xml::XMLDocument & doc, const char * field, int pos, void* pvApiCtx)
104 {
105     if (!strcmp("root", field))
106     {
107         const XMLElement * e = doc.getRoot();
108         if (!e)
109         {
110             Scierror(999, gettext("%s: No root element.\n"), fname, field);
111             return 0;
112         }
113         return e->createOnStack(pos, pvApiCtx);
114     }
115     else if (!strcmp("url", field))
116     {
117         return createStringOnStack(fname, doc.getDocumentURL(), pos, pvApiCtx);
118     }
119     else
120     {
121         Scierror(999, gettext("%s: Unknown field: %s\n"), fname, field);
122         return 0;
123     }
124 }
125 /*--------------------------------------------------------------------------*/
126
127 /**
128  * Creates a new variable on stack according to the requested field
129  * @param fname the function name
130  * @param elem the element
131  * @param field the field name
132  * @param pos the stack position
133  * @return 1 if all is ok, else 0
134  */
135 int createVariableOnStack(char * fname, XMLElement & elem, const char * field, int pos, void* pvApiCtx)
136 {
137     if (!strcmp("name", field))
138     {
139         return createStringOnStack(fname, elem.getNodeName(), pos, pvApiCtx);
140     }
141     else if (!strcmp("namespace", field))
142     {
143         const XMLNs * ns = elem.getNodeNameSpace();
144         if (ns)
145         {
146             return ns->createOnStack(pos, pvApiCtx);
147         }
148         else
149         {
150             createMatrixOfDouble(pvApiCtx, pos, 0, 0, 0);
151             return 1;
152         }
153     }
154     else if (!strcmp("content", field))
155     {
156         const char * content = elem.getNodeContent();
157         int ret = createStringOnStack(fname, content, pos, pvApiCtx);
158         xmlFree(const_cast<char *>(content));
159         return ret;
160     }
161     else if (!strcmp("type", field))
162     {
163         return createStringOnStack(fname, nodes_type[elem.getNodeType() - 1], pos, pvApiCtx);
164     }
165     else if (!strcmp("parent", field))
166     {
167         const XMLElement * parent = elem.getParentElement();
168         if (parent)
169         {
170             return parent->createOnStack(pos, pvApiCtx);
171         }
172         else
173         {
174             createMatrixOfDouble(pvApiCtx, pos, 0, 0, 0);
175             return 1;
176         }
177     }
178     else if (!strcmp("attributes", field))
179     {
180         return elem.getAttributes()->createOnStack(pos, pvApiCtx);
181     }
182     else if (!strcmp("children", field))
183     {
184         return elem.getChildren()->createOnStack(pos, pvApiCtx);
185     }
186     else if (!strcmp("line", field))
187     {
188         double line = (double)elem.getDefinitionLine();
189         SciErr err = createMatrixOfDouble(pvApiCtx, pos, 1, 1, &line);
190         if (err.iErr)
191         {
192             printError(&err, 0);
193             Scierror(999, _("%s: Memory allocation error.\n"), fname);
194             return 0;
195         }
196
197         return 1;
198     }
199     else
200     {
201         Scierror(999, gettext("%s: Unknown field: %s\n"), fname, field);
202     }
203     return 0;
204 }
205 /*--------------------------------------------------------------------------*/
206
207 /**
208  * Creates a new variable on stack according to the requested field
209  * @param fname the function name
210  * @param ns the namespace
211  * @param field the field name
212  * @param pos the stack position
213  * @return 1 if all is ok, else 0
214  */
215 int createVariableOnStack(char * fname, XMLNs & ns, const char * field, int pos, void* pvApiCtx)
216 {
217     if (!strcmp("href", field))
218     {
219         return createStringOnStack(fname, ns.getHref(), pos, pvApiCtx);
220     }
221     else if (!strcmp("prefix", field))
222     {
223         return createStringOnStack(fname, ns.getPrefix(), pos, pvApiCtx);
224     }
225     else
226     {
227         Scierror(999, gettext("%s: Unknown field: %s\n"), fname, field);
228         return 0;
229     }
230 }
231 /*--------------------------------------------------------------------------*/
232
233 /**
234  * Function to handle extraction in different XMLObjects
235  * @param fname the function name
236  * @param fname_len the function name length
237  */
238 template<class T>
239 int sci_extraction(char * fname, void *pvApiCtx)
240 {
241     T * t;
242     int id;
243     SciErr err;
244     int * fieldaddr = 0;
245     int * mlistaddr = 0;
246     char * field = 0;
247     int ret;
248
249     CheckLhs(1, 1);
250     CheckRhs(2, 2);
251
252     err = getVarAddressFromPosition(pvApiCtx, 1, &fieldaddr);
253     if (err.iErr)
254     {
255         printError(&err, 0);
256         return 0;
257     }
258
259     if (!isStringType(pvApiCtx, fieldaddr))
260     {
261         Scierror(999, gettext("%s: Wrong type for input argument #%i: A string expected.\n"), fname, 1);
262         return 0;
263     }
264
265     err = getVarAddressFromPosition(pvApiCtx, 2, &mlistaddr);
266     if (err.iErr)
267     {
268         printError(&err, 0);
269         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
270         return 0;
271     }
272
273     if (getAllocatedSingleString(pvApiCtx, fieldaddr, &field) != 0)
274     {
275         Scierror(999, _("%s: No more memory.\n"), fname);
276         return 0;
277     }
278     id = getXMLObjectId(mlistaddr, pvApiCtx);
279
280     t = XMLObject::getFromId<T>(id);
281     if (!t)
282     {
283         freeAllocatedSingleString(field);
284         Scierror(999, gettext("%s: XML object does not exist.\n"), fname);
285         return 0;
286     }
287
288     ret = createVariableOnStack(fname, *t, const_cast<char *>(field), Rhs + 1, pvApiCtx);
289     freeAllocatedSingleString(field);
290     if (ret)
291     {
292         LhsVar(1) = Rhs + 1;
293     }
294     else
295     {
296         LhsVar(1) = 0;
297     }
298     PutLhsVar();
299
300     return 0;
301 }