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