Update git submodules
[LibreOffice.git] / sc / source / filter / oox / connectionsbuffer.cxx
blob9d8fddaf59e9a334fb3c881685afb077ec58b0a1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <connectionsbuffer.hxx>
21 #include <biffhelper.hxx>
23 #include <osl/diagnose.h>
24 #include <oox/helper/attributelist.hxx>
25 #include <oox/token/namespaces.hxx>
26 #include <oox/token/tokens.hxx>
27 #include <oox/helper/binaryinputstream.hxx>
28 #include <sax/fastattribs.hxx>
29 #include <documentimport.hxx>
30 #include <document.hxx>
31 #include <sax/fshelper.hxx>
33 namespace oox::xls {
35 using namespace ::com::sun::star::uno;
37 namespace {
39 const sal_Int32 BIFF12_RECONNECT_AS_REQUIRED = 1;
41 const sal_uInt8 BIFF12_CONNECTION_SAVEPASSWORD_ON = 1;
43 const sal_uInt16 BIFF12_CONNECTION_KEEPALIVE = 0x0001;
44 const sal_uInt16 BIFF12_CONNECTION_NEW = 0x0002;
45 const sal_uInt16 BIFF12_CONNECTION_DELETED = 0x0004;
46 const sal_uInt16 BIFF12_CONNECTION_ONLYUSECONNFILE = 0x0008;
47 const sal_uInt16 BIFF12_CONNECTION_BACKGROUND = 0x0010;
48 const sal_uInt16 BIFF12_CONNECTION_REFRESHONLOAD = 0x0020;
49 const sal_uInt16 BIFF12_CONNECTION_SAVEDATA = 0x0040;
51 const sal_uInt16 BIFF12_CONNECTION_HAS_SOURCEFILE = 0x0001;
52 const sal_uInt16 BIFF12_CONNECTION_HAS_SOURCECONNFILE = 0x0002;
53 const sal_uInt16 BIFF12_CONNECTION_HAS_DESCRIPTION = 0x0004;
54 const sal_uInt16 BIFF12_CONNECTION_HAS_NAME = 0x0008;
55 const sal_uInt16 BIFF12_CONNECTION_HAS_SSOID = 0x0010;
57 const sal_uInt32 BIFF12_WEBPR_XML = 0x00000100;
58 const sal_uInt32 BIFF12_WEBPR_SOURCEDATA = 0x00000200;
59 const sal_uInt32 BIFF12_WEBPR_PARSEPRE = 0x00000400;
60 const sal_uInt32 BIFF12_WEBPR_CONSECUTIVE = 0x00000800;
61 const sal_uInt32 BIFF12_WEBPR_FIRSTROW = 0x00001000;
62 const sal_uInt32 BIFF12_WEBPR_XL97CREATED = 0x00002000;
63 const sal_uInt32 BIFF12_WEBPR_TEXTDATES = 0x00004000;
64 const sal_uInt32 BIFF12_WEBPR_XL2000REFRESHED = 0x00008000;
65 const sal_uInt32 BIFF12_WEBPR_HTMLTABLES = 0x00010000;
67 const sal_uInt8 BIFF12_WEBPR_HAS_POSTMETHOD = 0x01;
68 const sal_uInt8 BIFF12_WEBPR_HAS_EDITPAGE = 0x02;
69 const sal_uInt8 BIFF12_WEBPR_HAS_URL = 0x04;
71 } // namespace
73 WebPrModel::WebPrModel() :
74 mnCount( 0 ),
75 mnHtmlFormat( -1 ),
76 mbXml( false ),
77 mbSourceData( false ),
78 mbParsePre( false ),
79 mbConsecutive( false ),
80 mbFirstRow( false ),
81 mbXl97Created( false ),
82 mbTextDates( false ),
83 mbXl2000Refreshed( false ),
84 mbHtmlTables( false )
88 ConnectionModel::ConnectionModel() :
89 mnId( -1 ),
90 mnType( BIFF12_CONNECTION_UNKNOWN ),
91 mnReconnectMethod( BIFF12_RECONNECT_AS_REQUIRED ),
92 mnCredentials( -1 ),
93 mnInterval( 0 ),
94 mnRefreshedVersion(-1),
95 mnMinRefreshableVersion(0),
96 mbKeepAlive( false ),
97 mbNew( false ),
98 mbDeleted( false ),
99 mbOnlyUseConnFile( false ),
100 mbBackground( false ),
101 mbRefreshOnLoad( false ),
102 mbSaveData( false ),
103 mbSavePassword( false )
107 WebPrModel& ConnectionModel::createWebPr()
109 OSL_ENSURE( !mxWebPr, "ConnectionModel::createWebPr - multiple call" );
110 mxWebPr.reset( new WebPrModel );
111 return *mxWebPr;
114 TextPrModel& ConnectionModel::createTextPr()
116 OSL_ENSURE(!mxTextPr, "ConnectionModel::createTextPr - multiple call");
117 mxTextPr.reset(new TextPrModel);
118 return *mxTextPr;
121 ParametersModel& ConnectionModel::createParameters()
123 OSL_ENSURE(!mxParameters, "ConnectionModel::createParameters - multiple call");
124 mxParameters.reset(new ParametersModel);
125 return *mxParameters;
128 ExtensionListModel& ConnectionModel::createExtensionList()
130 OSL_ENSURE(!mxExtensionList, "ConnectionModel::createExtensionList - multiple call");
131 mxExtensionList.reset(new ExtensionListModel);
132 return *mxExtensionList;
135 Connection::Connection( const WorkbookHelper& rHelper ) :
136 WorkbookHelper( rHelper )
138 maModel.mnId = -1; // use="required"
139 maModel.mnRefreshedVersion = -1; // use="required"
142 void Connection::importConnection( const AttributeList& rAttribs )
144 maModel.maName = rAttribs.getXString( XML_name, OUString() );
145 maModel.maDescription = rAttribs.getXString( XML_description, OUString() );
146 maModel.maSourceFile = rAttribs.getXString( XML_sourceFile, OUString() );
147 maModel.maSourceConnFile = rAttribs.getXString( XML_odcFile, OUString() );
148 maModel.maSsoId = rAttribs.getXString( XML_singleSignOnId, OUString() );
149 maModel.mnId = rAttribs.getInteger( XML_id, -1 );
150 maModel.mnRefreshedVersion = rAttribs.getInteger(XML_refreshedVersion, -1);
151 maModel.mnMinRefreshableVersion = rAttribs.getInteger(XML_minRefreshableVersion, 0);
152 // type and reconnectionMethod are using the BIFF12 constants instead of XML tokens
153 maModel.mnType = rAttribs.getInteger( XML_type, BIFF12_CONNECTION_UNKNOWN );
154 maModel.mnReconnectMethod = rAttribs.getInteger( XML_reconnectionMethod, BIFF12_RECONNECT_AS_REQUIRED );
155 maModel.mnCredentials = rAttribs.getToken( XML_credentials, -1 );
156 maModel.mnInterval = rAttribs.getInteger( XML_interval, 0 );
157 maModel.mbKeepAlive = rAttribs.getBool( XML_keepAlive, false );
158 maModel.mbNew = rAttribs.getBool( XML_new, false );
159 maModel.mbDeleted = rAttribs.getBool( XML_deleted, false );
160 maModel.mbOnlyUseConnFile = rAttribs.getBool( XML_onlyUseConnectionFile, false );
161 maModel.mbBackground = rAttribs.getBool( XML_background, false );
162 maModel.mbRefreshOnLoad = rAttribs.getBool( XML_refreshOnLoad, false );
163 maModel.mbSaveData = rAttribs.getBool( XML_saveData, false );
164 maModel.mbSavePassword = rAttribs.getBool( XML_savePassword, false );
165 // FIXME: FSNS(XML_xr16, XML_uid) gets wrong(?) id of xr16:uid
166 // maModel.maXr16Uid = rAttribs.getXString( FSNS(XML_xr16, XML_uid), OUString() );
168 // workaround for finding correct XML id of xr16:uid
169 if (auto xFastAttributeList = rAttribs.getFastAttributeList())
171 css::uno::Sequence<css::xml::FastAttribute> aFast = xFastAttributeList->getFastAttributes();
173 for (auto& attr : aFast)
175 // xr16:uid="{...}" // tokenId = 3347856
176 if (attr.Value.startsWith("{"))
178 maModel.maXr16Uid = attr.Value;
179 break;
185 void Connection::importWebPr( const AttributeList& rAttribs )
187 WebPrModel& rWebPr = maModel.createWebPr();
189 rWebPr.maUrl = rAttribs.getXString( XML_url, OUString() );
190 rWebPr.maPostMethod = rAttribs.getXString( XML_post, OUString() );
191 rWebPr.maEditPage = rAttribs.getXString( XML_editPage, OUString() );
192 rWebPr.mnHtmlFormat = rAttribs.getToken( XML_htmlFormat, -1 );
193 rWebPr.mbXml = rAttribs.getBool( XML_xml, false );
194 rWebPr.mbSourceData = rAttribs.getBool( XML_sourceData, false );
195 rWebPr.mbParsePre = rAttribs.getBool( XML_parsePre, false );
196 rWebPr.mbConsecutive = rAttribs.getBool( XML_consecutive, false );
197 rWebPr.mbFirstRow = rAttribs.getBool( XML_firstRow, false );
198 rWebPr.mbXl97Created = rAttribs.getBool( XML_xl97, false );
199 rWebPr.mbTextDates = rAttribs.getBool( XML_textDates, false );
200 rWebPr.mbXl2000Refreshed = rAttribs.getBool( XML_xl2000, false );
201 rWebPr.mbHtmlTables = rAttribs.getBool( XML_htmlTables, false );
204 void Connection::importDbPr(const AttributeList& rAttribs)
206 if (auto xFastAttributeList = rAttribs.getFastAttributeList())
208 maModel.maDbPrSequenceAny = getSequenceOfAny(xFastAttributeList);
212 void Connection::importOlapPr(const AttributeList& rAttribs)
214 if (auto xFastAttributeList = rAttribs.getFastAttributeList())
216 maModel.maOlapPrSequenceAny = getSequenceOfAny(xFastAttributeList);
220 void Connection::importTables(const AttributeList& rAttribs)
222 if( maModel.mxWebPr )
224 OSL_ENSURE( maModel.mxWebPr->maTables.empty(), "Connection::importTables - multiple calls" );
225 maModel.mxWebPr->maTables.clear();
227 maModel.mxWebPr->mnCount = rAttribs.getInteger(XML_count, 0);
231 void Connection::importTable( const AttributeList& rAttribs, sal_Int32 nElement )
233 if( !maModel.mxWebPr )
234 return;
236 Any aTableAny;
237 switch( nElement )
239 case XLS_TOKEN(m): // no value
240 break;
241 case XLS_TOKEN(s): // character value
242 aTableAny <<= "s," + rAttribs.getXString(XML_v, OUString());
243 break;
244 case XLS_TOKEN(x): // shared items index
245 aTableAny <<= "x," + OUString::number(rAttribs.getInteger(XML_v, -1));
246 break;
247 default:
248 OSL_ENSURE( false, "Connection::importTable - unexpected element" );
249 return;
251 maModel.mxWebPr->maTables.push_back( aTableAny );
254 void Connection::importTextPr(const AttributeList& rAttribs)
256 TextPrModel& rTextPr = maModel.createTextPr();
258 if (auto xFastAttributeList = rAttribs.getFastAttributeList())
260 rTextPr.maTextPrSequenceAny = getSequenceOfAny(xFastAttributeList);
264 void Connection::importTextFields(const AttributeList& rAttribs)
266 if (maModel.mxTextPr)
268 OSL_ENSURE(maModel.mxTextPr->vTextField.empty(),
269 "Connection::importTextFields - multiple calls");
270 maModel.mxTextPr->vTextField.clear();
272 if (auto xFastAttributeList = rAttribs.getFastAttributeList())
274 maModel.mxTextPr->maTextFieldsSequenceAny = getSequenceOfAny(xFastAttributeList);
279 void Connection::importTextField(const AttributeList& rAttribs)
281 if (!maModel.mxTextPr)
282 return;
284 if (auto xFastAttributeList = rAttribs.getFastAttributeList())
286 maModel.mxTextPr->vTextField.push_back(getSequenceOfAny(xFastAttributeList));
290 void Connection::importParameters(const AttributeList& rAttribs)
292 ParametersModel& rParameters = maModel.createParameters();
293 maModel.mxParameters->vParameter.clear();
294 rParameters.mnCount = rAttribs.getInteger(XML_count, -1);
297 void Connection::importParameter(const AttributeList& rAttribs)
299 if (!maModel.mxParameters)
300 return;
302 if (auto xFastAttributeList = rAttribs.getFastAttributeList())
304 maModel.mxParameters->vParameter.push_back(getSequenceOfAny(xFastAttributeList));
308 void Connection::importExtensionList()
310 maModel.createExtensionList();
311 maModel.mxExtensionList->vExtension.clear();
314 void Connection::importExtension(const AttributeList& rAttribs)
316 if (!maModel.mxExtensionList)
317 return;
319 // store uri attributes of <ext> element
320 OUString sUri = rAttribs.getXString(XML_uri, OUString());
321 maModel.mxExtensionList->vExtension.push_back(sUri);
324 css::uno::Sequence<css::uno::Any> Connection::getSequenceOfAny(
325 css::uno::Reference<css::xml::sax::XFastAttributeList>& xFastAttributeList)
327 css::uno::Sequence<css::xml::FastAttribute> aFast = xFastAttributeList->getFastAttributes();
328 css::uno::Sequence<css::xml::Attribute> aUnk = xFastAttributeList->getUnknownAttributes();
329 return { css::uno::Any(aFast), css::uno::Any(aUnk) };
332 void Connection::importConnection( SequenceInputStream& rStrm )
334 // TODO: update import&export of Microsoft Excel Binary (XLSB) File Format
335 sal_uInt16 nFlags, nStrFlags;
336 sal_uInt8 nSavePassword, nCredentials;
337 rStrm.skip( 2 );
338 nSavePassword = rStrm.readuChar();
339 rStrm.skip( 1 );
340 maModel.mnInterval = rStrm.readuInt16();
341 nFlags = rStrm.readuInt16();
342 nStrFlags = rStrm.readuInt16();
343 maModel.mnType = rStrm.readInt32();
344 maModel.mnReconnectMethod = rStrm.readInt32();
345 maModel.mnId = rStrm.readInt32();
346 nCredentials = rStrm.readuChar();
348 if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SOURCEFILE ) )
349 rStrm >> maModel.maSourceFile;
350 if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SOURCECONNFILE ) )
351 rStrm >> maModel.maSourceConnFile;
352 if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_DESCRIPTION ) )
353 rStrm >> maModel.maDescription;
354 if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_NAME ) )
355 rStrm >> maModel.maName;
356 if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SSOID ) )
357 rStrm >> maModel.maSsoId;
359 static const sal_Int32 spnCredentials[] = { XML_integrated, XML_none, XML_stored, XML_prompt };
360 maModel.mnCredentials = STATIC_ARRAY_SELECT( spnCredentials, nCredentials, XML_integrated );
362 maModel.mbKeepAlive = getFlag( nFlags, BIFF12_CONNECTION_KEEPALIVE );
363 maModel.mbNew = getFlag( nFlags, BIFF12_CONNECTION_NEW );
364 maModel.mbDeleted = getFlag( nFlags, BIFF12_CONNECTION_DELETED );
365 maModel.mbOnlyUseConnFile = getFlag( nFlags, BIFF12_CONNECTION_ONLYUSECONNFILE );
366 maModel.mbBackground = getFlag( nFlags, BIFF12_CONNECTION_BACKGROUND );
367 maModel.mbRefreshOnLoad = getFlag( nFlags, BIFF12_CONNECTION_REFRESHONLOAD );
368 maModel.mbSaveData = getFlag( nFlags, BIFF12_CONNECTION_SAVEDATA );
369 maModel.mbSavePassword = nSavePassword == BIFF12_CONNECTION_SAVEPASSWORD_ON;
372 void Connection::importWebPr( SequenceInputStream& rStrm )
374 WebPrModel& rWebPr = maModel.createWebPr();
376 sal_uInt32 nFlags;
377 sal_uInt8 nStrFlags;
378 nFlags = rStrm.readuInt32();
379 nStrFlags = rStrm.readuChar();
381 if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_URL ) )
382 rStrm >> rWebPr.maUrl;
383 if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_POSTMETHOD ) )
384 rStrm >> rWebPr.maPostMethod;
385 if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_EDITPAGE ) )
386 rStrm >> rWebPr.maEditPage;
388 static const sal_Int32 spnHmlFormats[] = { XML_none, XML_rtf, XML_all };
389 rWebPr.mnHtmlFormat = STATIC_ARRAY_SELECT( spnHmlFormats, extractValue< sal_uInt8 >( nFlags, 0, 8 ), XML_none );
391 rWebPr.mbXml = getFlag( nFlags, BIFF12_WEBPR_XML );
392 rWebPr.mbSourceData = getFlag( nFlags, BIFF12_WEBPR_SOURCEDATA );
393 rWebPr.mbParsePre = getFlag( nFlags, BIFF12_WEBPR_PARSEPRE );
394 rWebPr.mbConsecutive = getFlag( nFlags, BIFF12_WEBPR_CONSECUTIVE );
395 rWebPr.mbFirstRow = getFlag( nFlags, BIFF12_WEBPR_FIRSTROW );
396 rWebPr.mbXl97Created = getFlag( nFlags, BIFF12_WEBPR_XL97CREATED );
397 rWebPr.mbTextDates = getFlag( nFlags, BIFF12_WEBPR_TEXTDATES );
398 rWebPr.mbXl2000Refreshed = getFlag( nFlags, BIFF12_WEBPR_XL2000REFRESHED );
399 rWebPr.mbHtmlTables = getFlag( nFlags, BIFF12_WEBPR_HTMLTABLES );
402 void Connection::importWebPrTables( SequenceInputStream& /*rStrm*/ )
404 if( maModel.mxWebPr )
406 OSL_ENSURE( maModel.mxWebPr->maTables.empty(), "Connection::importWebPrTables - multiple calls" );
407 maModel.mxWebPr->maTables.clear();
411 void Connection::importWebPrTable( SequenceInputStream& rStrm, sal_Int32 nRecId )
413 if( !maModel.mxWebPr )
414 return;
416 Any aTableAny;
417 switch( nRecId )
419 case BIFF12_ID_PCITEM_MISSING: break;
420 case BIFF12_ID_PCITEM_STRING: aTableAny <<= BiffHelper::readString( rStrm ); break;
421 case BIFF12_ID_PCITEM_INDEX: aTableAny <<= rStrm.readInt32(); break;
422 default:
423 OSL_ENSURE( false, "Connection::importWebPrTable - unexpected record" );
424 return;
426 maModel.mxWebPr->maTables.push_back( aTableAny );
429 ConnectionsBuffer::ConnectionsBuffer( const WorkbookHelper& rHelper ) :
430 WorkbookHelper( rHelper ),
431 mnUnusedId( 1 )
435 Connection& ConnectionsBuffer::createConnection()
437 ConnectionRef xConnection = std::make_shared<Connection>( *this );
438 maConnections.push_back( xConnection );
439 return *xConnection;
442 void ConnectionsBuffer::finalizeImport()
444 for( const auto& rxConnection : maConnections )
445 insertConnectionToMap( rxConnection );
447 ScDocument& rDoc = getDocImport().getDoc();
448 rDoc.setConnectionVector(maConnections);
451 ConnectionRef ConnectionsBuffer::getConnection( sal_Int32 nConnId ) const
453 return maConnectionsById.get( nConnId );
456 void ConnectionsBuffer::insertConnectionToMap( const ConnectionRef& rxConnection )
458 sal_Int32 nConnId = rxConnection->getConnectionId();
459 if( nConnId > 0 )
461 OSL_ENSURE( !maConnectionsById.has( nConnId ), "ConnectionsBuffer::insertConnectionToMap - multiple connection identifier" );
462 maConnectionsById[ nConnId ] = rxConnection;
463 mnUnusedId = ::std::max< sal_Int32 >( mnUnusedId, nConnId + 1 );
467 } // namespace oox::xls
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */