Use hxx extensions instead of hpp
[scilab.git] / scilab / modules / xml / sci_gateway / cpp / sci_xmlXPath.cpp
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 "xml.h"
14
15 extern "C"
16 {
17 #include "gw_xml.h"
18 #include "Scierror.h"
19 #include "api_scilab.h"
20 #include "xml_mlist.h"
21 #include "localization.h"
22 }
23
24 #include "XMLObject.hxx"
25 #include "XMLDocument.hxx"
26 #include "XMLElement.hxx"
27 #include "XMLXPath.hxx"
28 #include "XMLNodeSet.hxx"
29
30 using namespace org_modules_xml;
31
32 /*--------------------------------------------------------------------------*/
33 int sci_xmlXPath(char *fname, unsigned long fname_len)
34 {
35     int id;
36     SciErr err;
37
38     org_modules_xml::XMLDocument * doc;
39     XMLElement *where = 0;
40     const XMLXPath *xpath;
41     int *addr = 0;
42     char *query = 0;
43
44     std::string error;
45     int row = 0;
46     int col = 0;
47     char **namespaces = 0;
48     int isElem = 0;
49     bool mustDelete = true;
50
51     CheckLhs(1, 1);
52     CheckRhs(2, 3);
53
54     err = getVarAddressFromPosition(pvApiCtx, 1, &addr);
55     if (err.iErr)
56     {
57         printError(&err, 0);
58         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
59         return 0;
60     }
61
62     isElem = isXMLElem(addr, pvApiCtx);
63
64     if (!isElem && !isXMLDoc(addr, pvApiCtx))
65     {
66         Scierror(999, gettext("%s: Wrong type for input argument #%d: A XMLDoc or a XMLElem expected.\n"), fname, 1);
67         return 0;
68     }
69
70     id = getXMLObjectId(addr, pvApiCtx);
71     if (isElem)
72     {
73         where = XMLObject::getFromId < XMLElement > (id);
74         if (!where)
75         {
76             Scierror(999, gettext("%s: XML element does not exist.\n"), fname);
77             return 0;
78         }
79         doc = const_cast < org_modules_xml::XMLDocument * >(&(where->getXMLDocument()));
80     }
81     else
82     {
83         doc = XMLObject::getFromId < org_modules_xml::XMLDocument > (id);
84         if (!doc)
85         {
86             Scierror(999, gettext("%s: XML document does not exist.\n"), fname);
87             return 0;
88         }
89     }
90
91     err = getVarAddressFromPosition(pvApiCtx, 2, &addr);
92     if (err.iErr)
93     {
94         printError(&err, 0);
95         Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
96         return 0;
97     }
98
99     if (!isStringType(pvApiCtx, addr) || !checkVarDimension(pvApiCtx, addr, 1, 1))
100     {
101         Scierror(999, gettext("%s: Wrong type for input argument #%d: A string expected.\n"), fname, 2);
102         return 0;
103     }
104
105     if (getAllocatedSingleString(pvApiCtx, addr, &query) != 0)
106     {
107         Scierror(999, _("%s: No more memory.\n"), fname);
108         return 0;
109     }
110
111     if (Rhs == 3)
112     {
113         err = getVarAddressFromPosition(pvApiCtx, 3, &addr);
114         if (err.iErr)
115         {
116             freeAllocatedSingleString(query);
117             printError(&err, 0);
118             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 3);
119             return 0;
120         }
121
122         if (!isStringType(pvApiCtx, addr))
123         {
124             freeAllocatedSingleString(query);
125             Scierror(999, gettext("%s: Wrong type for input argument #%d: A string expected.\n"), fname, 2);
126             return 0;
127         }
128
129         err = getMatrixOfString(pvApiCtx, addr, &row, &col, 0, 0);
130         if (err.iErr)
131         {
132             freeAllocatedSingleString(query);
133             printError(&err, 0);
134             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
135             return 0;
136         }
137
138         if (col != 2)
139         {
140             freeAllocatedSingleString(query);
141             Scierror(999, gettext("%s: Bad number of columns for argument #%d: two expected.\n"), fname, 3);
142             return 0;
143         }
144
145         if (getAllocatedMatrixOfString(pvApiCtx, addr, &row, &col, &namespaces) != 0)
146         {
147             Scierror(999, _("%s: No more memory.\n"), fname);
148             return 0;
149         }
150     }
151
152     xpath = doc->makeXPathQuery(const_cast < const char *>(query), namespaces, row, where, &error);
153     freeAllocatedSingleString(query);
154     if (namespaces)
155     {
156         freeAllocatedMatrixOfString(row, col, namespaces);
157     }
158
159     if (!error.empty())
160     {
161         Scierror(999, gettext("%s: Bad XPath query:\n%s"), fname, error.c_str());
162         return 0;
163     }
164
165     switch (xpath->getResultType())
166     {
167     case XPATH_NODESET:
168     {
169         const XMLNodeSet *set = xpath->getNodeSet();
170
171         if (set->getSize() == 0)
172         {
173             createMatrixOfDouble(pvApiCtx, Rhs + 1, 0, 0, 0);
174         }
175         set->createOnStack(Rhs + 1, pvApiCtx);
176         mustDelete = false;
177         break;
178     }
179     case XPATH_BOOLEAN:
180     {
181         int b = xpath->getBooleanValue();
182
183         createScalarBoolean(pvApiCtx, Rhs + 1, b);
184         break;
185     }
186     case XPATH_NUMBER:
187     {
188         double d = xpath->getFloatValue();
189
190         createScalarDouble(pvApiCtx, Rhs + 1, d);
191         break;
192     }
193     case XPATH_STRING:
194     {
195         const char *str = xpath->getStringValue();
196
197         createSingleString(pvApiCtx, Rhs + 1, str);
198         break;
199     }
200     default:
201         delete xpath;
202         Scierror(999, gettext("%s: XPath query returned a not handled type: %i\n"), fname, xpath->getResultType());
203         return 0;
204     }
205
206     if (mustDelete)
207     {
208         xmlXPathObject *real = static_cast < xmlXPathObject * >(xpath->getRealXMLPointer());
209         delete xpath;
210
211         xmlXPathFreeObject(real);
212     }
213     else
214     {
215         delete xpath;
216     }
217
218     LhsVar(1) = Rhs + 1;
219     PutLhsVar();
220     return 0;
221 }
222
223 /*--------------------------------------------------------------------------*/