1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "oox/xls/connectionsbuffer.hxx"
25 
26 #include "oox/helper/attributelist.hxx"
27 #include "oox/xls/biffinputstream.hxx"
28 
29 namespace oox {
30 namespace xls {
31 
32 // ============================================================================
33 
34 using namespace ::com::sun::star::uno;
35 
36 using ::rtl::OUString;
37 using ::rtl::OUStringBuffer;
38 
39 // ============================================================================
40 
41 namespace {
42 
43 const sal_Int32 BIFF12_RECONNECT_AS_REQUIRED            = 1;
44 const sal_Int32 BIFF12_RECONNECT_ALWAYS                 = 2;
45 const sal_Int32 BIFF12_RECONNECT_NEVER                  = 3;
46 
47 const sal_uInt8 BIFF12_CONNECTION_SAVEPASSWORD_ON       = 1;
48 const sal_uInt8 BIFF12_CONNECTION_SAVEPASSWORD_OFF      = 2;
49 
50 const sal_uInt16 BIFF12_CONNECTION_KEEPALIVE            = 0x0001;
51 const sal_uInt16 BIFF12_CONNECTION_NEW                  = 0x0002;
52 const sal_uInt16 BIFF12_CONNECTION_DELETED              = 0x0004;
53 const sal_uInt16 BIFF12_CONNECTION_ONLYUSECONNFILE      = 0x0008;
54 const sal_uInt16 BIFF12_CONNECTION_BACKGROUND           = 0x0010;
55 const sal_uInt16 BIFF12_CONNECTION_REFRESHONLOAD        = 0x0020;
56 const sal_uInt16 BIFF12_CONNECTION_SAVEDATA             = 0x0040;
57 
58 const sal_uInt16 BIFF12_CONNECTION_HAS_SOURCEFILE       = 0x0001;
59 const sal_uInt16 BIFF12_CONNECTION_HAS_SOURCECONNFILE   = 0x0002;
60 const sal_uInt16 BIFF12_CONNECTION_HAS_DESCRIPTION      = 0x0004;
61 const sal_uInt16 BIFF12_CONNECTION_HAS_NAME             = 0x0008;
62 const sal_uInt16 BIFF12_CONNECTION_HAS_SSOID            = 0x0010;
63 
64 const sal_uInt32 BIFF12_WEBPR_XML                       = 0x00000100;
65 const sal_uInt32 BIFF12_WEBPR_SOURCEDATA                = 0x00000200;
66 const sal_uInt32 BIFF12_WEBPR_PARSEPRE                  = 0x00000400;
67 const sal_uInt32 BIFF12_WEBPR_CONSECUTIVE               = 0x00000800;
68 const sal_uInt32 BIFF12_WEBPR_FIRSTROW                  = 0x00001000;
69 const sal_uInt32 BIFF12_WEBPR_XL97CREATED               = 0x00002000;
70 const sal_uInt32 BIFF12_WEBPR_TEXTDATES                 = 0x00004000;
71 const sal_uInt32 BIFF12_WEBPR_XL2000REFRESHED           = 0x00008000;
72 const sal_uInt32 BIFF12_WEBPR_HTMLTABLES                = 0x00010000;
73 
74 const sal_uInt8 BIFF12_WEBPR_HAS_POSTMETHOD             = 0x01;
75 const sal_uInt8 BIFF12_WEBPR_HAS_EDITPAGE               = 0x02;
76 const sal_uInt8 BIFF12_WEBPR_HAS_URL                    = 0x04;
77 
78 const sal_uInt16 BIFF_DBQUERY_ODBC                      = 0x0008;
79 const sal_uInt16 BIFF_DBQUERY_SQLQUERY                  = 0x0010;
80 const sal_uInt16 BIFF_DBQUERY_SERVERBASEDSQL            = 0x0020;
81 const sal_uInt16 BIFF_DBQUERY_HTML                      = 0x0040;
82 const sal_uInt16 BIFF_DBQUERY_SAVEPASSWORD              = 0x0080;
83 const sal_uInt16 BIFF_DBQUERY_HTMLTABLES                = 0x0100;
84 
85 const sal_uInt16 BIFF_QTSETTINGS_KEEPALIVE              = 0x0001;
86 const sal_uInt16 BIFF_QTSETTINGS_NEW                    = 0x0002;
87 const sal_uInt16 BIFF_QTSETTINGS_SOURCEDATA             = 0x0004;
88 const sal_uInt16 BIFF_QTSETTINGS_WEBBASEDPROV           = 0x0008;
89 const sal_uInt16 BIFF_QTSETTINGS_REINITLIST             = 0x0010;
90 const sal_uInt16 BIFF_QTSETTINGS_XML                    = 0x0080;
91 
92 const sal_uInt16 BIFF_QTSETTINGS_PARSEPRE               = 0x0001;
93 const sal_uInt16 BIFF_QTSETTINGS_CONSECUTIVE            = 0x0002;
94 const sal_uInt16 BIFF_QTSETTINGS_FIRSTROW               = 0x0004;
95 const sal_uInt16 BIFF_QTSETTINGS_XL97CREATED            = 0x0008;
96 const sal_uInt16 BIFF_QTSETTINGS_TEXTDATES              = 0x0010;
97 const sal_uInt16 BIFF_QTSETTINGS_XL2000REFRESHED        = 0x0020;
98 
99 const sal_uInt16 BIFF_QTSETTINGS_TEXTQUERY              = 0x0001;
100 const sal_uInt16 BIFF_QTSETTINGS_TABLENAMES             = 0x0002;
101 
102 // ----------------------------------------------------------------------------
103 
104 OUString lclReadQueryString( BiffInputStream& rStrm, sal_uInt16 nCount )
105 {
106     bool bValidRec = true;
107     OUStringBuffer aBuffer;
108     for( sal_uInt16 nIndex = 0; bValidRec && (nIndex < nCount); ++nIndex )
109     {
110         bValidRec = (rStrm.getNextRecId() == BIFF_ID_PCITEM_STRING) && rStrm.startNextRecord();
111         if( bValidRec )
112             aBuffer.append( rStrm.readUniString() );
113     }
114     OSL_ENSURE( bValidRec, "lclReadQueryString - missing PCITEM_STRING records" );
115     return aBuffer.makeStringAndClear();
116 }
117 
118 void lclParseTables( WebPrModel::TablesVector& rTables, const OUString& rTableNames )
119 {
120     rTables.clear();
121     OUString aTableNames = rTableNames.trim();
122     while( aTableNames.getLength() > 0 )
123     {
124         sal_Int32 nSep = -1;
125         // table names are enclosed in double quotes
126         if( aTableNames[ 0 ] == '"' )
127         {
128             // search closing quote character
129             sal_Int32 nEndQuote = aTableNames.indexOf( '"', 1 );
130             OSL_ENSURE( nEndQuote >= 1, "lclParseTables - invalid syntax" );
131             if( nEndQuote < 0 )
132                 nEndQuote = aTableNames.getLength();
133             else
134                 nSep = aTableNames.indexOf( ',', nEndQuote + 1 );
135             // extract text between quote characters
136             OUString aTableName = aTableNames.copy( 1, nEndQuote - 1 ).trim();
137             if( aTableName.getLength() > 0 )
138                 rTables.push_back( Any( aTableName ) );
139             else
140                 rTables.push_back( Any() );
141         }
142         else
143         {
144             nSep = aTableNames.indexOf( ',' );
145             if( nSep < 0 )
146                 nSep = aTableNames.getLength();
147             OUString aTableIndex = aTableNames.copy( 0, nSep ).trim();
148             if( (aTableIndex.getLength() > 0) && (aTableIndex[ 0 ] >= '1') && (aTableIndex[ 0 ] <= '9') )
149                 rTables.push_back( Any( aTableIndex.toInt32() ) );
150             else
151                 rTables.push_back( Any() );
152         }
153 
154         // remove processed item from aTableNames
155         if( (nSep < 0) || (nSep >= aTableNames.getLength()) )
156             aTableNames = OUString();
157         else
158             aTableNames = aTableNames.copy( nSep + 1 ).trim();
159     }
160 }
161 
162 } // namespace
163 
164 // ============================================================================
165 
166 WebPrModel::WebPrModel() :
167     mnHtmlFormat( XML_none ),
168     mbXml( false ),
169     mbSourceData( false ),
170     mbParsePre( false ),
171     mbConsecutive( false ),
172     mbFirstRow( false ),
173     mbXl97Created( false ),
174     mbTextDates( false ),
175     mbXl2000Refreshed( false ),
176     mbHtmlTables( false )
177 {
178 }
179 
180 // ----------------------------------------------------------------------------
181 
182 ConnectionModel::ConnectionModel() :
183     mnId( -1 ),
184     mnType( BIFF12_CONNECTION_UNKNOWN ),
185     mnReconnectMethod( BIFF12_RECONNECT_AS_REQUIRED ),
186     mnCredentials( XML_integrated ),
187     mnInterval( 0 ),
188     mbKeepAlive( false ),
189     mbNew( false ),
190     mbDeleted( false ),
191     mbOnlyUseConnFile( false ),
192     mbBackground( false ),
193     mbRefreshOnLoad( false ),
194     mbSaveData( false ),
195     mbSavePassword( false )
196 {
197 }
198 
199 WebPrModel& ConnectionModel::createWebPr()
200 {
201     OSL_ENSURE( !mxWebPr.get(), "ConnectionModel::createWebPr - multiple call" );
202     mxWebPr.reset( new WebPrModel );
203     return *mxWebPr;
204 }
205 
206 // ----------------------------------------------------------------------------
207 
208 Connection::Connection( const WorkbookHelper& rHelper, sal_Int32 nConnId ) :
209     WorkbookHelper( rHelper )
210 {
211     maModel.mnId = nConnId;
212 }
213 
214 void Connection::importConnection( const AttributeList& rAttribs )
215 {
216     maModel.maName            = rAttribs.getXString( XML_name, OUString() );
217     maModel.maDescription     = rAttribs.getXString( XML_description, OUString() );
218     maModel.maSourceFile      = rAttribs.getXString( XML_sourceFile, OUString() );
219     maModel.maSourceConnFile  = rAttribs.getXString( XML_odcFile, OUString() );
220     maModel.maSsoId           = rAttribs.getXString( XML_singleSignOnId, OUString() );
221     maModel.mnId              = rAttribs.getInteger( XML_id, -1 );
222     // type and reconnectionMethod are using the BIFF12 constants instead of XML tokens
223     maModel.mnType            = rAttribs.getInteger( XML_type, BIFF12_CONNECTION_UNKNOWN );
224     maModel.mnReconnectMethod = rAttribs.getInteger( XML_reconnectionMethod, BIFF12_RECONNECT_AS_REQUIRED );
225     maModel.mnCredentials     = rAttribs.getToken( XML_credentials, XML_integrated );
226     maModel.mnInterval        = rAttribs.getInteger( XML_interval, 0 );
227     maModel.mbKeepAlive       = rAttribs.getBool( XML_keepAlive, false );
228     maModel.mbNew             = rAttribs.getBool( XML_new, false );
229     maModel.mbDeleted         = rAttribs.getBool( XML_deleted, false );
230     maModel.mbOnlyUseConnFile = rAttribs.getBool( XML_onlyUseConnectionFile, false );
231     maModel.mbBackground      = rAttribs.getBool( XML_background, false );
232     maModel.mbRefreshOnLoad   = rAttribs.getBool( XML_refreshOnLoad, false );
233     maModel.mbSaveData        = rAttribs.getBool( XML_saveData, false );
234     maModel.mbSavePassword    = rAttribs.getBool( XML_savePassword, false );
235 }
236 
237 void Connection::importWebPr( const AttributeList& rAttribs )
238 {
239     WebPrModel& rWebPr = maModel.createWebPr();
240 
241     rWebPr.maUrl             = rAttribs.getXString( XML_url, OUString() );
242     rWebPr.maPostMethod      = rAttribs.getXString( XML_post, OUString() );
243     rWebPr.maEditPage        = rAttribs.getXString( XML_editPage, OUString() );
244     rWebPr.mnHtmlFormat      = rAttribs.getToken( XML_htmlFormat, XML_none );
245     rWebPr.mbXml             = rAttribs.getBool( XML_xml, false );
246     rWebPr.mbSourceData      = rAttribs.getBool( XML_sourceData, false );
247     rWebPr.mbParsePre        = rAttribs.getBool( XML_parsePre, false );
248     rWebPr.mbConsecutive     = rAttribs.getBool( XML_consecutive, false );
249     rWebPr.mbFirstRow        = rAttribs.getBool( XML_firstRow, false );
250     rWebPr.mbXl97Created     = rAttribs.getBool( XML_xl97, false );
251     rWebPr.mbTextDates       = rAttribs.getBool( XML_textDates, false );
252     rWebPr.mbXl2000Refreshed = rAttribs.getBool( XML_xl2000, false );
253     rWebPr.mbHtmlTables      = rAttribs.getBool( XML_htmlTables, false );
254 }
255 
256 void Connection::importTables( const AttributeList& /*rAttribs*/ )
257 {
258     if( maModel.mxWebPr.get() )
259     {
260         OSL_ENSURE( maModel.mxWebPr->maTables.empty(), "Connection::importTables - multiple calls" );
261         maModel.mxWebPr->maTables.clear();
262     }
263 }
264 
265 void Connection::importTable( const AttributeList& rAttribs, sal_Int32 nElement )
266 {
267     if( maModel.mxWebPr.get() )
268     {
269         Any aTableAny;
270         switch( nElement )
271         {
272             case XLS_TOKEN( m ):                                                            break;
273             case XLS_TOKEN( s ):    aTableAny <<= rAttribs.getXString( XML_v, OUString() ); break;
274             case XLS_TOKEN( x ):    aTableAny <<= rAttribs.getInteger( XML_v, -1 );         break;
275             default:
276                 OSL_ENSURE( false, "Connection::importTable - unexpected element" );
277                 return;
278         }
279         maModel.mxWebPr->maTables.push_back( aTableAny );
280     }
281 }
282 
283 void Connection::importConnection( SequenceInputStream& rStrm )
284 {
285     sal_uInt16 nFlags, nStrFlags;
286     sal_uInt8 nSavePassword, nCredentials;
287     rStrm.skip( 2 );
288     rStrm >> nSavePassword;
289     rStrm.skip( 1 );
290     maModel.mnInterval = rStrm.readuInt16();
291     rStrm >> nFlags >> nStrFlags >> maModel.mnType >> maModel.mnReconnectMethod >> maModel.mnId >> nCredentials;
292 
293     if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SOURCEFILE ) )
294         rStrm >> maModel.maSourceFile;
295     if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SOURCECONNFILE ) )
296         rStrm >> maModel.maSourceConnFile;
297     if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_DESCRIPTION ) )
298         rStrm >> maModel.maDescription;
299     if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_NAME ) )
300         rStrm >> maModel.maName;
301     if( getFlag( nStrFlags, BIFF12_CONNECTION_HAS_SSOID ) )
302         rStrm >> maModel.maSsoId;
303 
304     static const sal_Int32 spnCredentials[] = { XML_integrated, XML_none, XML_stored, XML_prompt };
305     maModel.mnCredentials = STATIC_ARRAY_SELECT( spnCredentials, nCredentials, XML_integrated );
306 
307     maModel.mbKeepAlive       = getFlag( nFlags, BIFF12_CONNECTION_KEEPALIVE );
308     maModel.mbNew             = getFlag( nFlags, BIFF12_CONNECTION_NEW );
309     maModel.mbDeleted         = getFlag( nFlags, BIFF12_CONNECTION_DELETED );
310     maModel.mbOnlyUseConnFile = getFlag( nFlags, BIFF12_CONNECTION_ONLYUSECONNFILE );
311     maModel.mbBackground      = getFlag( nFlags, BIFF12_CONNECTION_BACKGROUND );
312     maModel.mbRefreshOnLoad   = getFlag( nFlags, BIFF12_CONNECTION_REFRESHONLOAD );
313     maModel.mbSaveData        = getFlag( nFlags, BIFF12_CONNECTION_SAVEDATA );
314     maModel.mbSavePassword    = nSavePassword == BIFF12_CONNECTION_SAVEPASSWORD_ON;
315 }
316 
317 void Connection::importWebPr( SequenceInputStream& rStrm )
318 {
319     WebPrModel& rWebPr = maModel.createWebPr();
320 
321     sal_uInt32 nFlags;
322     sal_uInt8 nStrFlags;
323     rStrm >> nFlags >> nStrFlags;
324 
325     if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_URL ) )
326         rStrm >> rWebPr.maUrl;
327     if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_POSTMETHOD ) )
328         rStrm >> rWebPr.maPostMethod;
329     if( getFlag( nStrFlags, BIFF12_WEBPR_HAS_EDITPAGE ) )
330         rStrm >> rWebPr.maEditPage;
331 
332     static const sal_Int32 spnHmlFormats[] = { XML_none, XML_rtf, XML_all };
333     rWebPr.mnHtmlFormat = STATIC_ARRAY_SELECT( spnHmlFormats, extractValue< sal_uInt8 >( nFlags, 0, 8 ), XML_none );
334 
335     rWebPr.mbXml             = getFlag( nFlags, BIFF12_WEBPR_XML );
336     rWebPr.mbSourceData      = getFlag( nFlags, BIFF12_WEBPR_SOURCEDATA );
337     rWebPr.mbParsePre        = getFlag( nFlags, BIFF12_WEBPR_PARSEPRE );
338     rWebPr.mbConsecutive     = getFlag( nFlags, BIFF12_WEBPR_CONSECUTIVE );
339     rWebPr.mbFirstRow        = getFlag( nFlags, BIFF12_WEBPR_FIRSTROW );
340     rWebPr.mbXl97Created     = getFlag( nFlags, BIFF12_WEBPR_XL97CREATED );
341     rWebPr.mbTextDates       = getFlag( nFlags, BIFF12_WEBPR_TEXTDATES );
342     rWebPr.mbXl2000Refreshed = getFlag( nFlags, BIFF12_WEBPR_XL2000REFRESHED );
343     rWebPr.mbHtmlTables      = getFlag( nFlags, BIFF12_WEBPR_HTMLTABLES );
344 }
345 
346 void Connection::importWebPrTables( SequenceInputStream& /*rStrm*/ )
347 {
348     if( maModel.mxWebPr.get() )
349     {
350         OSL_ENSURE( maModel.mxWebPr->maTables.empty(), "Connection::importWebPrTables - multiple calls" );
351         maModel.mxWebPr->maTables.clear();
352     }
353 }
354 
355 void Connection::importWebPrTable( SequenceInputStream& rStrm, sal_Int32 nRecId )
356 {
357     if( maModel.mxWebPr.get() )
358     {
359         Any aTableAny;
360         switch( nRecId )
361         {
362             case BIFF12_ID_PCITEM_MISSING:                                                  break;
363             case BIFF12_ID_PCITEM_STRING:   aTableAny <<= BiffHelper::readString( rStrm );  break;
364             case BIFF12_ID_PCITEM_INDEX:    aTableAny <<= rStrm.readInt32();                break;
365             default:
366                 OSL_ENSURE( false, "Connection::importWebPrTable - unexpected record" );
367                 return;
368         }
369         maModel.mxWebPr->maTables.push_back( aTableAny );
370     }
371 }
372 
373 void Connection::importDbQuery( BiffInputStream& rStrm )
374 {
375     sal_uInt16 nFlags, nSqlParamCount, nCommandCount, nPostMethodCount, nServerSqlCount, nOdbcConnCount;
376     rStrm >> nFlags >> nSqlParamCount >> nCommandCount >> nPostMethodCount >> nServerSqlCount >> nOdbcConnCount;
377 
378     // same type constants in all BIFF versions
379     maModel.mnType = extractValue< sal_Int32 >( nFlags, 0, 3 );
380     maModel.mbSavePassword = getFlag( nFlags, BIFF_DBQUERY_SAVEPASSWORD );
381 
382     OSL_ENSURE( getFlag( nFlags, BIFF_DBQUERY_ODBC ) == (maModel.mnType == BIFF12_CONNECTION_ODBC), "Connection::importDbQuery - wrong ODBC flag" );
383     OSL_ENSURE( getFlag( nFlags, BIFF_DBQUERY_SQLQUERY ) != (maModel.mnType == BIFF12_CONNECTION_HTML), "Connection::importDbQuery - wrong SQL query flag" );
384     OSL_ENSURE( getFlag( nFlags, BIFF_DBQUERY_HTML ) == (maModel.mnType == BIFF12_CONNECTION_HTML), "Connection::importDbQuery - wrong HTML flag" );
385 
386     if( (maModel.mnType == BIFF12_CONNECTION_HTML) && getFlag( nFlags, BIFF_DBQUERY_HTML ) )
387     {
388         WebPrModel& rWebPr = maModel.createWebPr();
389         rWebPr.mbHtmlTables = getFlag( nFlags, BIFF_DBQUERY_HTMLTABLES );
390 
391         // read HTML query URL and post method
392         rWebPr.maUrl = lclReadQueryString( rStrm, nCommandCount );
393         rWebPr.maPostMethod = lclReadQueryString( rStrm, nPostMethodCount );
394     }
395 }
396 
397 void Connection::importQueryTableSettings( BiffInputStream& rStrm )
398 {
399     rStrm.skip( 4 );
400     // source data type, again
401     sal_uInt16 nType = rStrm.readuInt16();
402     OSL_ENSURE( nType == maModel.mnType, "Connection::importQueryTableSettings - source data type mismatch" );
403     if( nType == maModel.mnType )
404     {
405         sal_uInt16 nFlags1, nFlags2, nFlags3, nHtmlFormat;
406         rStrm >> nFlags1 >> nFlags2 >> nFlags3;
407         rStrm.skip( 10 );
408         maModel.mnInterval = rStrm.readuInt16();
409         rStrm >> nHtmlFormat;
410 
411         // first flags field: generic connection flags
412         maModel.mbKeepAlive = getFlag( nFlags1, BIFF_QTSETTINGS_KEEPALIVE );
413         maModel.mbNew       = getFlag( nFlags1, BIFF_QTSETTINGS_NEW );
414 
415         // meaning of second flags field is dependent on source data type
416         if( (maModel.mnType == BIFF12_CONNECTION_HTML) && maModel.mxWebPr.get() )
417         {
418             WebPrModel& rWebPr = *maModel.mxWebPr;
419 
420             // HTML format is one-based in BIFF8 (but zero-based in BIFF12)
421             static const sal_Int32 spnHmlFormats[] = { XML_none, XML_none, XML_rtf, XML_all };
422             rWebPr.mnHtmlFormat = STATIC_ARRAY_SELECT( spnHmlFormats, nHtmlFormat, XML_none );
423 
424             rWebPr.mbXml             = getFlag( nFlags1, BIFF_QTSETTINGS_XML );
425             rWebPr.mbSourceData      = getFlag( nFlags1, BIFF_QTSETTINGS_SOURCEDATA );
426             rWebPr.mbParsePre        = getFlag( nFlags2, BIFF_QTSETTINGS_PARSEPRE );
427             rWebPr.mbConsecutive     = getFlag( nFlags2, BIFF_QTSETTINGS_CONSECUTIVE );
428             rWebPr.mbFirstRow        = getFlag( nFlags2, BIFF_QTSETTINGS_FIRSTROW );
429             rWebPr.mbXl97Created     = getFlag( nFlags2, BIFF_QTSETTINGS_XL97CREATED );
430             rWebPr.mbTextDates       = getFlag( nFlags2, BIFF_QTSETTINGS_TEXTDATES );
431             rWebPr.mbXl2000Refreshed = getFlag( nFlags2, BIFF_QTSETTINGS_XL2000REFRESHED );
432 
433             // list of HTML table names or indexes
434             if( getFlag( nFlags3, BIFF_QTSETTINGS_TABLENAMES ) )
435             {
436                 // a QUERYTABLESTRING record containing the table names must follow
437                 bool bHasQTString = (rStrm.getNextRecId() == BIFF_ID_QUERYTABLESTRING) && rStrm.startNextRecord();
438                 OSL_ENSURE( bHasQTString, "Connection::importQueryTableSettings - missing QUERYTABLESTRING record" );
439                 if( bHasQTString )
440                 {
441                     rStrm.skip( 4 );
442                     lclParseTables( rWebPr.maTables, rStrm.readUniString() );
443                 }
444             }
445         }
446     }
447 }
448 
449 // ============================================================================
450 
451 ConnectionsBuffer::ConnectionsBuffer( const WorkbookHelper& rHelper ) :
452     WorkbookHelper( rHelper ),
453     mnUnusedId( 1 )
454 {
455 }
456 
457 Connection& ConnectionsBuffer::createConnection()
458 {
459     ConnectionRef xConnection( new Connection( *this ) );
460     maConnections.push_back( xConnection );
461     return *xConnection;
462 }
463 
464 Connection& ConnectionsBuffer::createConnectionWithId()
465 {
466     ConnectionRef xConnection( new Connection( *this, mnUnusedId ) );
467     maConnections.push_back( xConnection );
468     insertConnectionToMap( xConnection );
469     return *xConnection;
470 }
471 
472 void ConnectionsBuffer::finalizeImport()
473 {
474     for( ConnectionVector::iterator aIt = maConnections.begin(), aEnd = maConnections.end(); aIt != aEnd; ++aIt )
475         insertConnectionToMap( *aIt );
476 }
477 
478 ConnectionRef ConnectionsBuffer::getConnection( sal_Int32 nConnId ) const
479 {
480     return maConnectionsById.get( nConnId );
481 }
482 
483 void ConnectionsBuffer::insertConnectionToMap( const ConnectionRef& rxConnection )
484 {
485     sal_Int32 nConnId = rxConnection->getConnectionId();
486     if( nConnId > 0 )
487     {
488         OSL_ENSURE( !maConnectionsById.has( nConnId ), "ConnectionsBuffer::insertConnectionToMap - multiple connection identifier" );
489         maConnectionsById[ nConnId ] = rxConnection;
490         mnUnusedId = ::std::max< sal_Int32 >( mnUnusedId, nConnId + 1 );
491     }
492 }
493 
494 // ============================================================================
495 
496 } // namespace xls
497 } // namespace oox
498