Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include "interpre.hxx"
11 : #include <rtl/strbuf.hxx>
12 : #include <formula/errorcodes.hxx>
13 : #include <svtools/miscopt.hxx>
14 :
15 : #include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
16 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
17 : #include <com/sun/star/io/XInputStream.hpp>
18 :
19 : #include "libxml/xpath.h"
20 : #include <datastreamgettime.hxx>
21 : #include <dpobject.hxx>
22 : #include <document.hxx>
23 :
24 : #include <boost/shared_ptr.hpp>
25 : #include <cstring>
26 :
27 : using namespace com::sun::star;
28 :
29 : // TODO: Add new methods for ScInterpreter here.
30 :
31 0 : void ScInterpreter::ScFilterXML()
32 : {
33 0 : sal_uInt8 nParamCount = GetByte();
34 0 : if (MustHaveParamCount( nParamCount, 2 ) )
35 : {
36 0 : OUString aXPathExpression = GetString().getString();
37 0 : OUString aString = GetString().getString();
38 0 : if(aString.isEmpty() || aXPathExpression.isEmpty())
39 : {
40 0 : PushError( errNoValue );
41 0 : return;
42 : }
43 :
44 0 : OString aOXPathExpression = OUStringToOString( aXPathExpression, RTL_TEXTENCODING_UTF8 );
45 0 : const char* pXPathExpr = aOXPathExpression.getStr();
46 0 : OString aOString = OUStringToOString( aString, RTL_TEXTENCODING_UTF8 );
47 0 : const char* pXML = aOString.getStr();
48 :
49 : boost::shared_ptr<xmlParserCtxt> pContext(
50 0 : xmlNewParserCtxt(), xmlFreeParserCtxt );
51 :
52 : boost::shared_ptr<xmlDoc> pDoc( xmlParseMemory( pXML, aOString.getLength() ),
53 0 : xmlFreeDoc );
54 :
55 0 : if(!pDoc)
56 : {
57 0 : PushError( errNoValue );
58 0 : return;
59 : }
60 :
61 : boost::shared_ptr<xmlXPathContext> pXPathCtx( xmlXPathNewContext(pDoc.get()),
62 0 : xmlXPathFreeContext );
63 :
64 : boost::shared_ptr<xmlXPathObject> pXPathObj( xmlXPathEvalExpression(BAD_CAST(pXPathExpr), pXPathCtx.get()),
65 0 : xmlXPathFreeObject );
66 :
67 0 : if(!pXPathObj)
68 : {
69 0 : PushError( errNoValue );
70 0 : return;
71 : }
72 :
73 0 : rtl::OUString aResult;
74 :
75 0 : switch(pXPathObj->type)
76 : {
77 : case XPATH_UNDEFINED:
78 0 : break;
79 : case XPATH_NODESET:
80 : {
81 0 : xmlNodeSetPtr pNodeSet = pXPathObj->nodesetval;
82 0 : if(!pNodeSet)
83 : {
84 0 : PushError( errNoValue );
85 0 : return;
86 : }
87 :
88 0 : size_t nSize = pNodeSet->nodeNr;
89 0 : if( nSize >= 1 )
90 : {
91 0 : if(pNodeSet->nodeTab[0]->type == XML_NAMESPACE_DECL)
92 : {
93 0 : xmlNsPtr ns = (xmlNsPtr)pNodeSet->nodeTab[0];
94 0 : xmlNodePtr cur = (xmlNodePtr)ns->next;
95 0 : boost::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree);
96 0 : aResult = OStringToOUString(OString((char*)pChar2.get()), RTL_TEXTENCODING_UTF8);
97 : }
98 : else
99 : {
100 0 : xmlNodePtr cur = pNodeSet->nodeTab[0];
101 0 : boost::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree);
102 0 : aResult = OStringToOUString(OString((char*)pChar2.get()), RTL_TEXTENCODING_UTF8);
103 : }
104 : }
105 : else
106 : {
107 0 : PushError( errNoValue );
108 0 : return;
109 : }
110 : }
111 0 : PushString(aResult);
112 0 : break;
113 : case XPATH_BOOLEAN:
114 : {
115 0 : bool bVal = pXPathObj->boolval != 0;
116 0 : PushDouble(double(bVal));
117 : }
118 0 : break;
119 : case XPATH_NUMBER:
120 : {
121 0 : double fVal = pXPathObj->floatval;
122 0 : PushDouble(fVal);
123 : }
124 0 : break;
125 : case XPATH_STRING:
126 0 : PushString(OUString::createFromAscii((char*)pXPathObj->stringval));
127 0 : break;
128 : case XPATH_POINT:
129 0 : PushNoValue();
130 0 : break;
131 : case XPATH_RANGE:
132 0 : PushNoValue();
133 0 : break;
134 : case XPATH_LOCATIONSET:
135 0 : PushNoValue();
136 0 : break;
137 : case XPATH_USERS:
138 0 : PushNoValue();
139 0 : break;
140 : case XPATH_XSLT_TREE:
141 0 : PushNoValue();
142 0 : break;
143 :
144 0 : }
145 : }
146 : }
147 :
148 0 : void ScInterpreter::ScWebservice()
149 : {
150 0 : sal_uInt8 nParamCount = GetByte();
151 0 : if (MustHaveParamCount( nParamCount, 1 ) )
152 : {
153 0 : OUString aURI = GetString().getString();
154 :
155 0 : if(aURI.isEmpty())
156 : {
157 0 : PushError( errNoValue );
158 0 : return;
159 : }
160 :
161 0 : uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY );
162 0 : if(!xFileAccess.is())
163 : {
164 0 : PushError( errNoValue );
165 0 : return;
166 : }
167 :
168 0 : uno::Reference< io::XInputStream > xStream;
169 : try {
170 0 : xStream = xFileAccess->openFileRead( aURI );
171 : }
172 0 : catch (...)
173 : {
174 : // don't let any exceptions pass
175 0 : PushError( errNoValue );
176 0 : return;
177 : }
178 0 : if ( !xStream.is() )
179 : {
180 0 : PushError( errNoValue );
181 0 : return;
182 : }
183 :
184 0 : const sal_Int32 BUF_LEN = 8000;
185 0 : uno::Sequence< sal_Int8 > buffer( BUF_LEN );
186 0 : OStringBuffer aBuffer( 64000 );
187 :
188 0 : sal_Int32 nRead = 0;
189 0 : while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN )
190 : {
191 0 : aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
192 : }
193 :
194 0 : if ( nRead > 0 )
195 : {
196 0 : aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead );
197 : }
198 :
199 0 : xStream->closeInput();
200 :
201 0 : OUString aContent = OStringToOUString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
202 0 : PushString( aContent );
203 : }
204 : }
205 :
206 0 : void ScInterpreter::ScDebugVar()
207 : {
208 : // This is to be used by developers only! Never document this for end
209 : // users. This is a convenient way to extract arbitrary internal state to
210 : // a cell for easier debugging.
211 :
212 0 : SvtMiscOptions aMiscOptions;
213 0 : if (!aMiscOptions.IsExperimentalMode())
214 : {
215 0 : PushError(ScErrorCodes::errNoName);
216 0 : return;
217 : }
218 :
219 0 : if (!MustHaveParamCount(GetByte(), 1))
220 : {
221 0 : PushIllegalParameter();
222 0 : return;
223 : }
224 :
225 0 : rtl_uString* p = GetString().getDataIgnoreCase();
226 0 : if (!p)
227 : {
228 0 : PushIllegalParameter();
229 0 : return;
230 : }
231 :
232 0 : OUString aStrUpper(p);
233 :
234 0 : if (aStrUpper == "PIVOTCOUNT")
235 : {
236 : // Set the number of pivot tables in the document.
237 :
238 0 : double fVal = 0.0;
239 0 : if (pDok->HasPivotTable())
240 : {
241 0 : const ScDPCollection* pDPs = pDok->GetDPCollection();
242 0 : fVal = pDPs->GetCount();
243 : }
244 0 : PushDouble(fVal);
245 : }
246 0 : else if (aStrUpper == "DATASTREAM_IMPORT")
247 0 : PushDouble( sc::datastream_get_time( 0 ) );
248 0 : else if (aStrUpper == "DATASTREAM_RECALC")
249 0 : PushDouble( sc::datastream_get_time( 1 ) );
250 0 : else if (aStrUpper == "DATASTREAM_RENDER")
251 0 : PushDouble( sc::datastream_get_time( 2 ) );
252 : else
253 0 : PushIllegalParameter();
254 : }
255 :
256 6 : void ScInterpreter::ScErf()
257 : {
258 6 : sal_uInt8 nParamCount = GetByte();
259 6 : if (MustHaveParamCount( nParamCount, 1 ) )
260 : {
261 6 : double x = GetDouble();
262 6 : PushDouble( ::rtl::math::erf( x ) );
263 : }
264 6 : }
265 :
266 6 : void ScInterpreter::ScErfc()
267 : {
268 6 : sal_uInt8 nParamCount = GetByte();
269 6 : if (MustHaveParamCount( nParamCount, 1 ) )
270 : {
271 6 : double x = GetDouble();
272 6 : PushDouble( ::rtl::math::erfc( x ) );
273 : }
274 6 : }
275 :
276 0 : void ScInterpreter::ScColor()
277 : {
278 0 : sal_uInt8 nParamCount = GetByte();
279 0 : if(MustHaveParamCount(nParamCount, 3, 4))
280 : {
281 0 : double nAlpha = 0;
282 0 : if(nParamCount == 4)
283 0 : nAlpha = rtl::math::approxFloor(GetDouble());
284 :
285 0 : if(nAlpha < 0 || nAlpha > 255)
286 : {
287 0 : PushIllegalArgument();
288 0 : return;
289 : }
290 :
291 0 : double nBlue = rtl::math::approxFloor(GetDouble());
292 :
293 0 : if(nBlue < 0 || nBlue > 255)
294 : {
295 0 : PushIllegalArgument();
296 0 : return;
297 : }
298 :
299 0 : double nGreen = rtl::math::approxFloor(GetDouble());
300 :
301 0 : if(nGreen < 0 || nGreen > 255)
302 : {
303 0 : PushIllegalArgument();
304 0 : return;
305 : }
306 :
307 0 : double nRed = rtl::math::approxFloor(GetDouble());
308 :
309 0 : if(nRed < 0 || nRed > 255)
310 : {
311 0 : PushIllegalArgument();
312 0 : return;
313 : }
314 :
315 0 : double nVal = 256*256*256*nAlpha + 256*256*nRed + 256*nGreen + nBlue;
316 0 : PushDouble(nVal);
317 : }
318 228 : }
319 :
320 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|