Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <stdarg.h>
30 : : #include <stdio.h>
31 : : #include <string.h>
32 : : #include <utility>
33 : :
34 : : #include <rtl/ustring.hxx>
35 : : #include <rtl/ustrbuf.hxx>
36 : : #include <rtl/random.h>
37 : : #include <sax/fshelper.hxx>
38 : : #include <unotools/streamwrap.hxx>
39 : :
40 : : #include "docuno.hxx"
41 : : #include "xestream.hxx"
42 : : #include "xladdress.hxx"
43 : : #include "xlstring.hxx"
44 : : #include "xeroot.hxx"
45 : : #include "xestyle.hxx"
46 : : #include "xcl97rec.hxx"
47 : : #include "rangelst.hxx"
48 : : #include "compiler.hxx"
49 : :
50 : : #include <../../ui/inc/docsh.hxx>
51 : : #include <../../ui/inc/viewdata.hxx>
52 : : #include <excdoc.hxx>
53 : :
54 : : #include <oox/token/tokens.hxx>
55 : : #include <formula/grammar.hxx>
56 : : #include <oox/export/drawingml.hxx>
57 : : #include <excelvbaproject.hxx>
58 : :
59 : : #include <sfx2/docfile.hxx>
60 : : #include <sfx2/objsh.hxx>
61 : : #include <sfx2/app.hxx>
62 : : #include <cppuhelper/implementationentry.hxx>
63 : :
64 : : #define DEBUG_XL_ENCRYPTION 0
65 : :
66 : : using ::com::sun::star::beans::PropertyValue;
67 : : using ::com::sun::star::embed::XStorage;
68 : : using ::com::sun::star::io::XOutputStream;
69 : : using ::com::sun::star::io::XStream;
70 : : using ::com::sun::star::lang::XComponent;
71 : : using ::com::sun::star::lang::XMultiServiceFactory;
72 : : using ::com::sun::star::lang::XServiceInfo;
73 : : using ::com::sun::star::lang::XSingleServiceFactory;
74 : : using ::com::sun::star::registry::InvalidRegistryException;
75 : : using ::com::sun::star::registry::XRegistryKey;
76 : : using ::com::sun::star::uno::Exception;
77 : : using ::com::sun::star::uno::Reference;
78 : : using ::com::sun::star::uno::Sequence;
79 : : using ::com::sun::star::uno::UNO_QUERY;
80 : : using ::com::sun::star::uno::XInterface;
81 : : using ::rtl::OString;
82 : : using ::rtl::OUString;
83 : : using ::rtl::OUStringBuffer;
84 : : using ::utl::OStreamWrapper;
85 : : using ::std::vector;
86 : :
87 : : using namespace ::com::sun::star::beans;
88 : : using namespace ::com::sun::star::io;
89 : : using namespace ::com::sun::star::lang;
90 : : using namespace ::com::sun::star::sheet;
91 : : using namespace ::com::sun::star::uno;
92 : : using namespace ::formula;
93 : : using namespace ::oox;
94 : :
95 : : // ============================================================================
96 : :
97 : 0 : XclExpStream::XclExpStream( SvStream& rOutStrm, const XclExpRoot& rRoot, sal_uInt16 nMaxRecSize ) :
98 : : mrStrm( rOutStrm ),
99 : : mrRoot( rRoot ),
100 : : mnMaxRecSize( nMaxRecSize ),
101 : : mnCurrMaxSize( 0 ),
102 : : mnMaxSliceSize( 0 ),
103 : : mnHeaderSize( 0 ),
104 : : mnCurrSize( 0 ),
105 : : mnSliceSize( 0 ),
106 : : mnPredictSize( 0 ),
107 : : mnLastSizePos( 0 ),
108 : 0 : mbInRec( false )
109 : : {
110 [ # # ]: 0 : if( mnMaxRecSize == 0 )
111 [ # # ]: 0 : mnMaxRecSize = (mrRoot.GetBiff() <= EXC_BIFF5) ? EXC_MAXRECSIZE_BIFF5 : EXC_MAXRECSIZE_BIFF8;
112 : 0 : mnMaxContSize = mnMaxRecSize;
113 : 0 : }
114 : :
115 : 0 : XclExpStream::~XclExpStream()
116 : : {
117 [ # # ]: 0 : mrStrm.Flush();
118 : 0 : }
119 : :
120 : 0 : void XclExpStream::StartRecord( sal_uInt16 nRecId, sal_Size nRecSize )
121 : : {
122 : : OSL_ENSURE( !mbInRec, "XclExpStream::StartRecord - another record still open" );
123 : 0 : DisableEncryption();
124 : 0 : mnMaxContSize = mnCurrMaxSize = mnMaxRecSize;
125 : 0 : mnPredictSize = nRecSize;
126 : 0 : mbInRec = true;
127 : 0 : InitRecord( nRecId );
128 : 0 : SetSliceSize( 0 );
129 : 0 : EnableEncryption();
130 : 0 : }
131 : :
132 : 0 : void XclExpStream::EndRecord()
133 : : {
134 : : OSL_ENSURE( mbInRec, "XclExpStream::EndRecord - no record open" );
135 : 0 : DisableEncryption();
136 : 0 : UpdateRecSize();
137 : 0 : mrStrm.Seek( STREAM_SEEK_TO_END );
138 : 0 : mbInRec = false;
139 : 0 : }
140 : :
141 : 0 : void XclExpStream::SetSliceSize( sal_uInt16 nSize )
142 : : {
143 : 0 : mnMaxSliceSize = nSize;
144 : 0 : mnSliceSize = 0;
145 : 0 : }
146 : :
147 : 0 : XclExpStream& XclExpStream::operator<<( sal_Int8 nValue )
148 : : {
149 : 0 : PrepareWrite( 1 );
150 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ]
151 : 0 : mxEncrypter->Encrypt(mrStrm, nValue);
152 : : else
153 : 0 : mrStrm << nValue;
154 : 0 : return *this;
155 : : }
156 : :
157 : 0 : XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue )
158 : : {
159 : 0 : PrepareWrite( 1 );
160 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ]
161 : 0 : mxEncrypter->Encrypt(mrStrm, nValue);
162 : : else
163 : 0 : mrStrm << nValue;
164 : 0 : return *this;
165 : : }
166 : :
167 : 0 : XclExpStream& XclExpStream::operator<<( sal_Int16 nValue )
168 : : {
169 : 0 : PrepareWrite( 2 );
170 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ]
171 : 0 : mxEncrypter->Encrypt(mrStrm, nValue);
172 : : else
173 : 0 : mrStrm << nValue;
174 : 0 : return *this;
175 : : }
176 : :
177 : 0 : XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue )
178 : : {
179 : 0 : PrepareWrite( 2 );
180 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ]
181 : 0 : mxEncrypter->Encrypt(mrStrm, nValue);
182 : : else
183 : 0 : mrStrm << nValue;
184 : 0 : return *this;
185 : : }
186 : :
187 : 0 : XclExpStream& XclExpStream::operator<<( sal_Int32 nValue )
188 : : {
189 : 0 : PrepareWrite( 4 );
190 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ]
191 : 0 : mxEncrypter->Encrypt(mrStrm, nValue);
192 : : else
193 : 0 : mrStrm << nValue;
194 : 0 : return *this;
195 : : }
196 : :
197 : 0 : XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue )
198 : : {
199 : 0 : PrepareWrite( 4 );
200 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ]
201 : 0 : mxEncrypter->Encrypt(mrStrm, nValue);
202 : : else
203 : 0 : mrStrm << nValue;
204 : 0 : return *this;
205 : : }
206 : :
207 : 0 : XclExpStream& XclExpStream::operator<<( float fValue )
208 : : {
209 : 0 : PrepareWrite( 4 );
210 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ]
211 : 0 : mxEncrypter->Encrypt(mrStrm, fValue);
212 : : else
213 : 0 : mrStrm << fValue;
214 : 0 : return *this;
215 : : }
216 : :
217 : 0 : XclExpStream& XclExpStream::operator<<( double fValue )
218 : : {
219 : 0 : PrepareWrite( 8 );
220 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ]
221 : 0 : mxEncrypter->Encrypt(mrStrm, fValue);
222 : : else
223 : 0 : mrStrm << fValue;
224 : 0 : return *this;
225 : : }
226 : :
227 : 0 : sal_Size XclExpStream::Write( const void* pData, sal_Size nBytes )
228 : : {
229 : 0 : sal_Size nRet = 0;
230 [ # # ][ # # ]: 0 : if( pData && (nBytes > 0) )
231 : : {
232 [ # # ]: 0 : if( mbInRec )
233 : : {
234 : 0 : const sal_uInt8* pBuffer = reinterpret_cast< const sal_uInt8* >( pData );
235 : 0 : sal_Size nBytesLeft = nBytes;
236 : 0 : bool bValid = true;
237 : :
238 [ # # ][ # # ]: 0 : while( bValid && (nBytesLeft > 0) )
[ # # ]
239 : : {
240 [ # # ][ # # ]: 0 : sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
241 : 0 : sal_Size nWriteRet = nWriteLen;
242 [ # # ][ # # ]: 0 : if (mbUseEncrypter && HasValidEncrypter())
[ # # ][ # # ]
243 : : {
244 : : OSL_ENSURE(nWriteLen > 0, "XclExpStream::Write: write length is 0!");
245 [ # # ]: 0 : vector<sal_uInt8> aBytes(nWriteLen);
246 [ # # ]: 0 : memcpy(&aBytes[0], pBuffer, nWriteLen);
247 [ # # ]: 0 : mxEncrypter->EncryptBytes(mrStrm, aBytes);
248 : : // TODO: How do I check if all the bytes have been successfully written ?
249 : : }
250 : : else
251 : : {
252 [ # # ]: 0 : nWriteRet = mrStrm.Write( pBuffer, nWriteLen );
253 : 0 : bValid = (nWriteLen == nWriteRet);
254 : : OSL_ENSURE( bValid, "XclExpStream::Write - stream write error" );
255 : : }
256 : 0 : pBuffer += nWriteRet;
257 : 0 : nRet += nWriteRet;
258 : 0 : nBytesLeft -= nWriteRet;
259 : 0 : UpdateSizeVars( nWriteRet );
260 : : }
261 : : }
262 : : else
263 : 0 : nRet = mrStrm.Write( pData, nBytes );
264 : : }
265 : 0 : return nRet;
266 : : }
267 : :
268 : 0 : void XclExpStream::WriteZeroBytes( sal_Size nBytes )
269 : : {
270 [ # # ]: 0 : if( mbInRec )
271 : : {
272 : 0 : sal_Size nBytesLeft = nBytes;
273 [ # # ]: 0 : while( nBytesLeft > 0 )
274 : : {
275 [ # # ][ # # ]: 0 : sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
276 [ # # ]: 0 : WriteRawZeroBytes( nWriteLen );
277 : 0 : nBytesLeft -= nWriteLen;
278 : 0 : UpdateSizeVars( nWriteLen );
279 : : }
280 : : }
281 : : else
282 : 0 : WriteRawZeroBytes( nBytes );
283 : 0 : }
284 : :
285 : 0 : void XclExpStream::WriteZeroBytesToRecord( sal_Size nBytes )
286 : : {
287 [ # # ]: 0 : if (!mbInRec)
288 : : // not in record.
289 : 0 : return;
290 : :
291 : 0 : sal_uInt8 nZero = 0;
292 [ # # ]: 0 : for (sal_Size i = 0; i < nBytes; ++i)
293 : 0 : *this << nZero;
294 : : }
295 : :
296 : 0 : sal_Size XclExpStream::CopyFromStream( SvStream& rInStrm, sal_Size nBytes )
297 : : {
298 : 0 : sal_Size nStrmPos = rInStrm.Tell();
299 [ # # ]: 0 : rInStrm.Seek( STREAM_SEEK_TO_END );
300 : 0 : sal_Size nStrmSize = rInStrm.Tell();
301 [ # # ]: 0 : rInStrm.Seek( nStrmPos );
302 : :
303 [ # # ]: 0 : sal_Size nBytesLeft = ::std::min( nBytes, nStrmSize - nStrmPos );
304 : 0 : sal_Size nRet = 0;
305 [ # # ]: 0 : if( nBytesLeft > 0 )
306 : : {
307 : 0 : const sal_Size nMaxBuffer = 4096;
308 [ # # ][ # # ]: 0 : sal_uInt8* pBuffer = new sal_uInt8[ ::std::min( nBytesLeft, nMaxBuffer ) ];
309 : 0 : bool bValid = true;
310 : :
311 [ # # ][ # # ]: 0 : while( bValid && (nBytesLeft > 0) )
[ # # ]
312 : : {
313 [ # # ]: 0 : sal_Size nWriteLen = ::std::min( nBytesLeft, nMaxBuffer );
314 [ # # ]: 0 : rInStrm.Read( pBuffer, nWriteLen );
315 [ # # ]: 0 : sal_Size nWriteRet = Write( pBuffer, nWriteLen );
316 : 0 : bValid = (nWriteLen == nWriteRet);
317 : 0 : nRet += nWriteRet;
318 : 0 : nBytesLeft -= nWriteRet;
319 : : }
320 [ # # ]: 0 : delete[] pBuffer;
321 : : }
322 : 0 : return nRet;
323 : : }
324 : :
325 : 0 : void XclExpStream::WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags )
326 : : {
327 : 0 : SetSliceSize( 0 );
328 : 0 : nFlags &= EXC_STRF_16BIT; // repeat only 16bit flag
329 [ # # ]: 0 : sal_uInt16 nCharLen = nFlags ? 2 : 1;
330 : :
331 : 0 : ScfUInt16Vec::const_iterator aEnd = rBuffer.end();
332 [ # # ][ # # ]: 0 : for( ScfUInt16Vec::const_iterator aIter = rBuffer.begin(); aIter != aEnd; ++aIter )
[ # # ]
333 : : {
334 [ # # ][ # # ]: 0 : if( mbInRec && (mnCurrSize + nCharLen > mnCurrMaxSize) )
335 : : {
336 [ # # ]: 0 : StartContinue();
337 [ # # ]: 0 : operator<<( nFlags );
338 : : }
339 [ # # ]: 0 : if( nCharLen == 2 )
340 [ # # ][ # # ]: 0 : operator<<( *aIter );
341 : : else
342 [ # # ][ # # ]: 0 : operator<<( static_cast< sal_uInt8 >( *aIter ) );
343 : : }
344 : 0 : }
345 : :
346 : : // Xcl has an obscure sense of whether starting a new record or not,
347 : : // and crashes if it encounters the string header at the very end of a record.
348 : : // Thus we add 1 to give some room, seems like they do it that way but with another count (10?)
349 : 0 : void XclExpStream::WriteByteString( const rtl::OString& rString, sal_uInt16 nMaxLen, bool b16BitCount )
350 : : {
351 : 0 : SetSliceSize( 0 );
352 [ # # ]: 0 : sal_Size nLen = ::std::min< sal_Size >( rString.getLength(), nMaxLen );
353 [ # # ]: 0 : if( !b16BitCount )
354 [ # # ]: 0 : nLen = ::std::min< sal_Size >( nLen, 0xFF );
355 : :
356 [ # # ]: 0 : sal_uInt16 nLeft = PrepareWrite();
357 [ # # ]: 0 : sal_uInt16 nLenFieldSize = b16BitCount ? 2 : 1;
358 [ # # ][ # # ]: 0 : if( mbInRec && (nLeft <= nLenFieldSize) )
359 [ # # ]: 0 : StartContinue();
360 : :
361 [ # # ]: 0 : if( b16BitCount )
362 [ # # ]: 0 : operator<<( static_cast< sal_uInt16 >( nLen ) );
363 : : else
364 [ # # ]: 0 : operator<<( static_cast< sal_uInt8 >( nLen ) );
365 [ # # ]: 0 : Write( rString.getStr(), nLen );
366 : 0 : }
367 : :
368 : 0 : void XclExpStream::WriteCharBuffer( const ScfUInt8Vec& rBuffer )
369 : : {
370 : 0 : SetSliceSize( 0 );
371 : 0 : Write( &rBuffer[ 0 ], rBuffer.size() );
372 : 0 : }
373 : :
374 : 0 : void XclExpStream::SetEncrypter( XclExpEncrypterRef xEncrypter )
375 : : {
376 : 0 : mxEncrypter = xEncrypter;
377 : 0 : }
378 : :
379 : 0 : bool XclExpStream::HasValidEncrypter() const
380 : : {
381 [ # # ][ # # ]: 0 : return mxEncrypter && mxEncrypter->IsValid();
382 : : }
383 : :
384 : 0 : void XclExpStream::EnableEncryption( bool bEnable )
385 : : {
386 [ # # ][ # # ]: 0 : mbUseEncrypter = bEnable && HasValidEncrypter();
387 : 0 : }
388 : :
389 : 0 : void XclExpStream::DisableEncryption()
390 : : {
391 : 0 : EnableEncryption(false);
392 : 0 : }
393 : :
394 : 0 : sal_Size XclExpStream::SetSvStreamPos( sal_Size nPos )
395 : : {
396 : : OSL_ENSURE( !mbInRec, "XclExpStream::SetSvStreamPos - not allowed inside of a record" );
397 [ # # ]: 0 : return mbInRec ? 0 : mrStrm.Seek( nPos );
398 : : }
399 : :
400 : : // private --------------------------------------------------------------------
401 : :
402 : 0 : void XclExpStream::InitRecord( sal_uInt16 nRecId )
403 : : {
404 : 0 : mrStrm.Seek( STREAM_SEEK_TO_END );
405 : 0 : mrStrm << nRecId;
406 : :
407 : 0 : mnLastSizePos = mrStrm.Tell();
408 [ # # ]: 0 : mnHeaderSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( mnPredictSize, mnCurrMaxSize ) );
409 : 0 : mrStrm << mnHeaderSize;
410 : 0 : mnCurrSize = mnSliceSize = 0;
411 : 0 : }
412 : :
413 : 0 : void XclExpStream::UpdateRecSize()
414 : : {
415 [ # # ]: 0 : if( mnCurrSize != mnHeaderSize )
416 : : {
417 : 0 : mrStrm.Seek( mnLastSizePos );
418 : 0 : mrStrm << mnCurrSize;
419 : : }
420 : 0 : }
421 : :
422 : 0 : void XclExpStream::UpdateSizeVars( sal_Size nSize )
423 : : {
424 : : OSL_ENSURE( mnCurrSize + nSize <= mnCurrMaxSize, "XclExpStream::UpdateSizeVars - record overwritten" );
425 : 0 : mnCurrSize = mnCurrSize + static_cast< sal_uInt16 >( nSize );
426 : :
427 [ # # ]: 0 : if( mnMaxSliceSize > 0 )
428 : : {
429 : : OSL_ENSURE( mnSliceSize + nSize <= mnMaxSliceSize, "XclExpStream::UpdateSizeVars - slice overwritten" );
430 : 0 : mnSliceSize = mnSliceSize + static_cast< sal_uInt16 >( nSize );
431 [ # # ]: 0 : if( mnSliceSize >= mnMaxSliceSize )
432 : 0 : mnSliceSize = 0;
433 : : }
434 : 0 : }
435 : :
436 : 0 : void XclExpStream::StartContinue()
437 : : {
438 : 0 : UpdateRecSize();
439 : 0 : mnCurrMaxSize = mnMaxContSize;
440 : 0 : mnPredictSize -= mnCurrSize;
441 : 0 : InitRecord( EXC_ID_CONT );
442 : 0 : }
443 : :
444 : 0 : void XclExpStream::PrepareWrite( sal_uInt16 nSize )
445 : : {
446 [ # # ]: 0 : if( mbInRec )
447 : : {
448 [ # # ][ # # ]: 0 : if( (mnCurrSize + nSize > mnCurrMaxSize) ||
[ # # ][ # # ]
449 : : ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
450 : 0 : StartContinue();
451 : 0 : UpdateSizeVars( nSize );
452 : : }
453 : 0 : }
454 : :
455 : 0 : sal_uInt16 XclExpStream::PrepareWrite()
456 : : {
457 : 0 : sal_uInt16 nRet = 0;
458 [ # # ]: 0 : if( mbInRec )
459 : : {
460 [ # # ][ # # ]: 0 : if( (mnCurrSize >= mnCurrMaxSize) ||
[ # # ][ # # ]
461 : : ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
462 : 0 : StartContinue();
463 : 0 : UpdateSizeVars( 0 );
464 : :
465 [ # # ]: 0 : nRet = (mnMaxSliceSize > 0) ? (mnMaxSliceSize - mnSliceSize) : (mnCurrMaxSize - mnCurrSize);
466 : : }
467 : 0 : return nRet;
468 : : }
469 : :
470 : 0 : void XclExpStream::WriteRawZeroBytes( sal_Size nBytes )
471 : : {
472 : 0 : const sal_uInt32 nData = 0;
473 : 0 : sal_Size nBytesLeft = nBytes;
474 [ # # ]: 0 : while( nBytesLeft >= sizeof( nData ) )
475 : : {
476 [ # # ]: 0 : mrStrm << nData;
477 : 0 : nBytesLeft -= sizeof( nData );
478 : : }
479 [ # # ]: 0 : if( nBytesLeft )
480 [ # # ]: 0 : mrStrm.Write( &nData, nBytesLeft );
481 : 0 : }
482 : :
483 : : // ============================================================================
484 : :
485 : 0 : XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot ) :
486 : : mrRoot(rRoot),
487 : : mnOldPos(STREAM_SEEK_TO_END),
488 : 0 : mbValid(false)
489 : : {
490 [ # # ]: 0 : Sequence< NamedValue > aEncryptionData = rRoot.GetEncryptionData();
491 [ # # ]: 0 : if( !aEncryptionData.hasElements() )
492 : : // Empty password. Get the default biff8 password.
493 [ # # ][ # # ]: 0 : aEncryptionData = rRoot.GenerateDefaultEncryptionData();
[ # # ]
494 [ # # ][ # # ]: 0 : Init( aEncryptionData );
495 : 0 : }
496 : :
497 : 0 : XclExpBiff8Encrypter::~XclExpBiff8Encrypter()
498 : : {
499 : 0 : }
500 : :
501 : 0 : bool XclExpBiff8Encrypter::IsValid() const
502 : : {
503 : 0 : return mbValid;
504 : : }
505 : :
506 : 0 : void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const
507 : : {
508 : : if ( sizeof( mpnSaltDigest ) == 16 )
509 : 0 : memcpy( pnSaltDigest, mpnSaltDigest, 16 );
510 : 0 : }
511 : :
512 : 0 : void XclExpBiff8Encrypter::GetSalt( sal_uInt8 pnSalt[16] ) const
513 : : {
514 : : if ( sizeof( mpnSalt ) == 16 )
515 : 0 : memcpy( pnSalt, mpnSalt, 16 );
516 : 0 : }
517 : :
518 : 0 : void XclExpBiff8Encrypter::GetDocId( sal_uInt8 pnDocId[16] ) const
519 : : {
520 : : if ( sizeof( mpnDocId ) == 16 )
521 : 0 : memcpy( pnDocId, mpnDocId, 16 );
522 : 0 : }
523 : :
524 : 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt8 nData )
525 : : {
526 [ # # ]: 0 : vector<sal_uInt8> aByte(1);
527 [ # # ]: 0 : aByte[0] = nData;
528 [ # # ]: 0 : EncryptBytes(rStrm, aByte);
529 : 0 : }
530 : :
531 : 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt16 nData )
532 : : {
533 [ # # ]: 0 : ::std::vector<sal_uInt8> pnBytes(2);
534 [ # # ]: 0 : pnBytes[0] = nData & 0xFF;
535 [ # # ]: 0 : pnBytes[1] = (nData >> 8) & 0xFF;
536 [ # # ]: 0 : EncryptBytes(rStrm, pnBytes);
537 : 0 : }
538 : :
539 : 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt32 nData )
540 : : {
541 [ # # ]: 0 : ::std::vector<sal_uInt8> pnBytes(4);
542 [ # # ]: 0 : pnBytes[0] = nData & 0xFF;
543 [ # # ]: 0 : pnBytes[1] = (nData >> 8) & 0xFF;
544 [ # # ]: 0 : pnBytes[2] = (nData >> 16) & 0xFF;
545 [ # # ]: 0 : pnBytes[3] = (nData >> 24) & 0xFF;
546 [ # # ]: 0 : EncryptBytes(rStrm, pnBytes);
547 : 0 : }
548 : :
549 : 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, float fValue )
550 : : {
551 [ # # ]: 0 : ::std::vector<sal_uInt8> pnBytes(4);
552 [ # # ]: 0 : memcpy(&pnBytes[0], &fValue, 4);
553 [ # # ]: 0 : EncryptBytes(rStrm, pnBytes);
554 : 0 : }
555 : :
556 : 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, double fValue )
557 : : {
558 [ # # ]: 0 : ::std::vector<sal_uInt8> pnBytes(8);
559 [ # # ]: 0 : memcpy(&pnBytes[0], &fValue, 8);
560 [ # # ]: 0 : EncryptBytes(rStrm, pnBytes);
561 : 0 : }
562 : :
563 : 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int8 nData )
564 : : {
565 : 0 : Encrypt(rStrm, static_cast<sal_uInt8>(nData));
566 : 0 : }
567 : :
568 : 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int16 nData )
569 : : {
570 : 0 : Encrypt(rStrm, static_cast<sal_uInt16>(nData));
571 : 0 : }
572 : :
573 : 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int32 nData )
574 : : {
575 : 0 : Encrypt(rStrm, static_cast<sal_uInt32>(nData));
576 : 0 : }
577 : :
578 : 0 : void XclExpBiff8Encrypter::Init( const Sequence< NamedValue >& rEncryptionData )
579 : : {
580 : 0 : mbValid = false;
581 : :
582 [ # # ]: 0 : if( maCodec.InitCodec( rEncryptionData ) )
583 : : {
584 [ # # ]: 0 : maCodec.GetDocId( mpnDocId );
585 : :
586 : : // generate the salt here
587 : : TimeValue aTime;
588 [ # # ]: 0 : osl_getSystemTime( &aTime );
589 : 0 : rtlRandomPool aRandomPool = rtl_random_createPool ();
590 : 0 : rtl_random_addBytes( aRandomPool, &aTime, 8 );
591 : 0 : rtl_random_getBytes( aRandomPool, mpnSalt, 16 );
592 : 0 : rtl_random_destroyPool( aRandomPool );
593 : :
594 : 0 : memset( mpnSaltDigest, 0, sizeof( mpnSaltDigest ) );
595 : :
596 : : // generate salt hash.
597 [ # # ]: 0 : ::msfilter::MSCodec_Std97 aCodec;
598 [ # # ]: 0 : aCodec.InitCodec( rEncryptionData );
599 [ # # ]: 0 : aCodec.CreateSaltDigest( mpnSalt, mpnSaltDigest );
600 : :
601 : : // verify to make sure it's in good shape.
602 [ # # ][ # # ]: 0 : mbValid = maCodec.VerifyKey( mpnSalt, mpnSaltDigest );
603 : : }
604 : 0 : }
605 : :
606 : 0 : sal_uInt32 XclExpBiff8Encrypter::GetBlockPos( sal_Size nStrmPos ) const
607 : : {
608 : 0 : return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
609 : : }
610 : :
611 : 0 : sal_uInt16 XclExpBiff8Encrypter::GetOffsetInBlock( sal_Size nStrmPos ) const
612 : : {
613 : 0 : return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
614 : : }
615 : :
616 : 0 : void XclExpBiff8Encrypter::EncryptBytes( SvStream& rStrm, vector<sal_uInt8>& aBytes )
617 : : {
618 : 0 : sal_Size nStrmPos = rStrm.Tell();
619 : 0 : sal_uInt16 nBlockOffset = GetOffsetInBlock(nStrmPos);
620 : 0 : sal_uInt32 nBlockPos = GetBlockPos(nStrmPos);
621 : :
622 : : #if DEBUG_XL_ENCRYPTION
623 : : fprintf(stdout, "XclExpBiff8Encrypter::EncryptBytes: stream pos = %ld offset in block = %d block pos = %ld\n",
624 : : nStrmPos, nBlockOffset, nBlockPos);
625 : : #endif
626 : :
627 : 0 : sal_uInt16 nSize = static_cast< sal_uInt16 >( aBytes.size() );
628 [ # # ]: 0 : if (nSize == 0)
629 : 0 : return;
630 : :
631 : : #if DEBUG_XL_ENCRYPTION
632 : : fprintf(stdout, "RAW: ");
633 : : for (sal_uInt16 i = 0; i < nSize; ++i)
634 : : fprintf(stdout, "%2.2X ", aBytes[i]);
635 : : fprintf(stdout, "\n");
636 : : #endif
637 : :
638 [ # # ]: 0 : if (mnOldPos != nStrmPos)
639 : : {
640 : 0 : sal_uInt16 nOldOffset = GetOffsetInBlock(mnOldPos);
641 : 0 : sal_uInt32 nOldBlockPos = GetBlockPos(mnOldPos);
642 : :
643 [ # # ][ # # ]: 0 : if ( (nBlockPos != nOldBlockPos) || (nBlockOffset < nOldOffset) )
644 : : {
645 [ # # ]: 0 : maCodec.InitCipher(nBlockPos);
646 : 0 : nOldOffset = 0;
647 : : }
648 : :
649 [ # # ]: 0 : if (nBlockOffset > nOldOffset)
650 [ # # ]: 0 : maCodec.Skip(nBlockOffset - nOldOffset);
651 : : }
652 : :
653 : 0 : sal_uInt16 nBytesLeft = nSize;
654 : 0 : sal_uInt16 nPos = 0;
655 [ # # ]: 0 : while (nBytesLeft > 0)
656 : : {
657 : 0 : sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - nBlockOffset;
658 [ # # ]: 0 : sal_uInt16 nEncBytes = ::std::min(nBlockLeft, nBytesLeft);
659 : :
660 [ # # ][ # # ]: 0 : bool bRet = maCodec.Encode(&aBytes[nPos], nEncBytes, &aBytes[nPos], nEncBytes);
[ # # ]
661 : : OSL_ENSURE(bRet, "XclExpBiff8Encrypter::EncryptBytes: encryption failed!!");
662 : : (void) bRet; // to remove a silly compiler warning.
663 : :
664 [ # # ][ # # ]: 0 : sal_Size nRet = rStrm.Write(&aBytes[nPos], nEncBytes);
665 : : OSL_ENSURE(nRet == nEncBytes, "XclExpBiff8Encrypter::EncryptBytes: fail to write to stream!!");
666 : : (void) nRet; // to remove a silly compiler warning.
667 : :
668 : 0 : nStrmPos = rStrm.Tell();
669 : 0 : nBlockOffset = GetOffsetInBlock(nStrmPos);
670 : 0 : nBlockPos = GetBlockPos(nStrmPos);
671 [ # # ]: 0 : if (nBlockOffset == 0)
672 [ # # ]: 0 : maCodec.InitCipher(nBlockPos);
673 : :
674 : 0 : nBytesLeft -= nEncBytes;
675 : 0 : nPos += nEncBytes;
676 : : }
677 : 0 : mnOldPos = nStrmPos;
678 : : }
679 : :
680 : 0 : static const char* lcl_GetErrorString( sal_uInt16 nScErrCode )
681 : : {
682 : 0 : sal_uInt8 nXclErrCode = XclTools::GetXclErrorCode( nScErrCode );
683 [ # # # # : 0 : switch( nXclErrCode )
# # # ]
684 : : {
685 : 0 : case EXC_ERR_NULL: return "#NULL!";
686 : 0 : case EXC_ERR_DIV0: return "#DIV/0!";
687 : 0 : case EXC_ERR_VALUE: return "#VALUE!";
688 : 0 : case EXC_ERR_REF: return "#REF!";
689 : 0 : case EXC_ERR_NAME: return "#NAME?";
690 : 0 : case EXC_ERR_NUM: return "#NUM!";
691 : : case EXC_ERR_NA:
692 : 0 : default: return "#N/A";
693 : : }
694 : : }
695 : :
696 : 0 : void XclXmlUtils::GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& rsType, OUString& rsValue )
697 : : {
698 [ # # # # ]: 0 : switch( rCell.GetFormatType() )
699 : : {
700 : : case NUMBERFORMAT_NUMBER:
701 : : {
702 : : // either value or error code
703 : 0 : sal_uInt16 nScErrCode = rCell.GetErrCode();
704 [ # # ]: 0 : if( nScErrCode )
705 : : {
706 : 0 : rsType = "e";
707 : 0 : rsValue = ToOUString( lcl_GetErrorString( nScErrCode ) );
708 : : }
709 : : else
710 : : {
711 : 0 : rsType = "n";
712 : 0 : rsValue = OUString::valueOf( rCell.GetValue() );
713 : : }
714 : : }
715 : 0 : break;
716 : :
717 : : case NUMBERFORMAT_TEXT:
718 : : {
719 : 0 : rsType = "str";
720 [ # # ][ # # ]: 0 : String aResult = rCell.GetString();
721 [ # # ]: 0 : rsValue = ToOUString( aResult );
722 : : }
723 : 0 : break;
724 : :
725 : : case NUMBERFORMAT_LOGICAL:
726 : : {
727 : 0 : rsType = "b";
728 [ # # ]: 0 : rsValue = ToOUString( rCell.GetValue() == 0.0 ? "0" : "1" );
729 : : }
730 : 0 : break;
731 : :
732 : : default:
733 : : {
734 : 0 : rsType = "inlineStr";
735 [ # # ][ # # ]: 0 : String aResult = rCell.GetString();
736 [ # # ]: 0 : rsValue = ToOUString( aResult );
737 : : }
738 : 0 : break;
739 : : }
740 : 0 : }
741 : :
742 : 0 : rtl::OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId )
743 : : {
744 : 0 : OUStringBuffer sBuf;
745 [ # # ]: 0 : if( sStreamDir )
746 [ # # ]: 0 : sBuf.appendAscii( sStreamDir );
747 [ # # ]: 0 : sBuf.appendAscii( sStream );
748 [ # # ]: 0 : if( nId )
749 [ # # ]: 0 : sBuf.append( nId );
750 [ # # ]: 0 : if( strstr(sStream, "vml") )
751 [ # # ]: 0 : sBuf.appendAscii( ".vml" );
752 : : else
753 [ # # ]: 0 : sBuf.appendAscii( ".xml" );
754 [ # # ]: 0 : return sBuf.makeStringAndClear();
755 : : }
756 : :
757 : 0 : OString XclXmlUtils::ToOString( const Color& rColor )
758 : : {
759 : : char buf[9];
760 : 0 : sprintf( buf, "%.2X%.2X%.2X%.2X", rColor.GetTransparency(), rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue() );
761 : 0 : buf[8] = '\0';
762 : 0 : return OString( buf );
763 : : }
764 : :
765 : 0 : OString XclXmlUtils::ToOString( const OUString& s )
766 : : {
767 : 0 : return OUStringToOString( s, RTL_TEXTENCODING_UTF8 );
768 : : }
769 : :
770 : 0 : OString XclXmlUtils::ToOString( const String& s )
771 : : {
772 : 0 : return OString( s.GetBuffer(), s.Len(), RTL_TEXTENCODING_UTF8 );
773 : : }
774 : :
775 : 0 : OString XclXmlUtils::ToOString( const ScAddress& rAddress )
776 : : {
777 [ # # ]: 0 : String sAddress;
778 [ # # ]: 0 : rAddress.Format( sAddress, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1 ) );
779 [ # # ][ # # ]: 0 : return ToOString( sAddress );
780 : : }
781 : :
782 : 0 : OString XclXmlUtils::ToOString( const ScfUInt16Vec& rBuffer )
783 : : {
784 : 0 : const sal_uInt16* pBuffer = &rBuffer [0];
785 : 0 : return OString( pBuffer, rBuffer.size(), RTL_TEXTENCODING_UTF8 );
786 : : }
787 : :
788 : 0 : OString XclXmlUtils::ToOString( const ScRange& rRange )
789 : : {
790 [ # # ]: 0 : String sRange;
791 [ # # ]: 0 : rRange.Format( sRange, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1 ) );
792 [ # # ][ # # ]: 0 : return ToOString( sRange );
793 : : }
794 : :
795 : 0 : OString XclXmlUtils::ToOString( const ScRangeList& rRangeList )
796 : : {
797 [ # # ]: 0 : String s;
798 [ # # ]: 0 : rRangeList.Format( s, SCA_VALID, NULL, FormulaGrammar::CONV_XL_A1, ' ' );
799 [ # # ][ # # ]: 0 : return ToOString( s );
800 : : }
801 : :
802 : 0 : static ScAddress lcl_ToAddress( const XclAddress& rAddress )
803 : : {
804 : 0 : ScAddress aAddress;
805 : :
806 : : // For some reason, ScRange::Format() returns omits row numbers if
807 : : // the row is >= MAXROW or the column is >= MAXCOL, and Excel doesn't
808 : : // like "A:IV" (i.e. no row numbers). Prevent this.
809 : : // KOHEI: Find out if the above comment is still true.
810 [ # # ]: 0 : aAddress.SetRow( std::min<sal_Int32>( rAddress.mnRow, MAXROW ) );
811 [ # # ]: 0 : aAddress.SetCol( static_cast<sal_Int16>(std::min<sal_Int32>( rAddress.mnCol, MAXCOL )) );
812 : :
813 : 0 : return aAddress;
814 : : }
815 : :
816 : 0 : OString XclXmlUtils::ToOString( const XclAddress& rAddress )
817 : : {
818 [ # # ]: 0 : return ToOString( lcl_ToAddress( rAddress ) );
819 : : }
820 : :
821 : 0 : OString XclXmlUtils::ToOString( const XclExpString& s )
822 : : {
823 : : OSL_ENSURE( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
824 : 0 : return ToOString( s.GetUnicodeBuffer() );
825 : : }
826 : :
827 : 0 : static ScRange lcl_ToRange( const XclRange& rRange )
828 : : {
829 : 0 : ScRange aRange;
830 : :
831 : 0 : aRange.aStart = lcl_ToAddress( rRange.maFirst );
832 : 0 : aRange.aEnd = lcl_ToAddress( rRange.maLast );
833 : :
834 : 0 : return aRange;
835 : : }
836 : :
837 : 0 : rtl::OString XclXmlUtils::ToOString( const XclRange& rRange )
838 : : {
839 [ # # ]: 0 : return ToOString( lcl_ToRange( rRange ) );
840 : : }
841 : :
842 : 0 : rtl::OString XclXmlUtils::ToOString( const XclRangeList& rRanges )
843 : : {
844 [ # # ]: 0 : ScRangeList aRanges;
845 [ # # ][ # # ]: 0 : for( XclRangeList::const_iterator i = rRanges.begin(), end = rRanges.end();
846 : : i != end; ++i )
847 : : {
848 [ # # ][ # # ]: 0 : aRanges.Append( lcl_ToRange( *i ) );
849 : : }
850 [ # # ][ # # ]: 0 : return ToOString( aRanges );
851 : : }
852 : :
853 : 0 : OUString XclXmlUtils::ToOUString( const char* s )
854 : : {
855 : 0 : return OUString( s, (sal_Int32) strlen( s ), RTL_TEXTENCODING_ASCII_US );
856 : : }
857 : :
858 : 0 : OUString XclXmlUtils::ToOUString( const ScfUInt16Vec& rBuf, sal_Int32 nStart, sal_Int32 nLength )
859 : : {
860 [ # # ][ # # ]: 0 : if( nLength == -1 || ( nLength > ((sal_Int32)rBuf.size() - nStart) ) )
[ # # ]
861 : 0 : nLength = (rBuf.size() - nStart);
862 : :
863 [ # # ]: 0 : return (nLength > 0) ? OUString( &rBuf[nStart], nLength ) : OUString();
864 : : }
865 : :
866 : 0 : OUString XclXmlUtils::ToOUString( const String& s )
867 : : {
868 : 0 : return OUString( s.GetBuffer(), s.Len() );
869 : : }
870 : :
871 : 0 : OUString XclXmlUtils::ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray )
872 : : {
873 [ # # ]: 0 : ScCompiler aCompiler( &rDocument, rAddress, *pTokenArray);
874 [ # # ]: 0 : aCompiler.SetGrammar(FormulaGrammar::GRAM_ENGLISH_XL_A1);
875 [ # # ]: 0 : String s;
876 [ # # ]: 0 : aCompiler.CreateStringFromTokenArray( s );
877 [ # # ][ # # ]: 0 : return ToOUString( s );
878 : : }
879 : :
880 : 0 : OUString XclXmlUtils::ToOUString( const XclExpString& s )
881 : : {
882 : : OSL_ENSURE( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
883 : 0 : return ToOUString( s.GetUnicodeBuffer() );
884 : : }
885 : :
886 : 0 : const char* XclXmlUtils::ToPsz( bool b )
887 : : {
888 [ # # ]: 0 : return b ? "true" : "false";
889 : : }
890 : :
891 : 0 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue )
892 : : {
893 : 0 : pStream->startElement( nElement, FSEND );
894 : 0 : pStream->write( nValue );
895 : 0 : pStream->endElement( nElement );
896 : :
897 : 0 : return pStream;
898 : : }
899 : :
900 : 0 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int64 nValue )
901 : : {
902 : 0 : pStream->startElement( nElement, FSEND );
903 : 0 : pStream->write( nValue );
904 : 0 : pStream->endElement( nElement );
905 : :
906 : 0 : return pStream;
907 : : }
908 : :
909 : 0 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const char* sValue )
910 : : {
911 : 0 : pStream->startElement( nElement, FSEND );
912 : 0 : pStream->write( sValue );
913 : 0 : pStream->endElement( nElement );
914 : :
915 : 0 : return pStream;
916 : : }
917 : :
918 : 0 : static void lcl_WriteValue( sax_fastparser::FSHelperPtr& rStream, sal_Int32 nElement, const char* pValue )
919 : : {
920 [ # # ]: 0 : if( !pValue )
921 : 0 : return;
922 : : rStream->singleElement( nElement,
923 : : XML_val, pValue,
924 : 0 : FSEND );
925 : : }
926 : :
927 : 0 : static const char* lcl_GetUnderlineStyle( FontUnderline eUnderline, bool& bHaveUnderline )
928 : : {
929 : 0 : bHaveUnderline = true;
930 [ # # # ]: 0 : switch( eUnderline )
931 : : {
932 : : // OOXTODO: doubleAccounting, singleAccounting
933 : : // OOXTODO: what should be done with the other FontUnderline values?
934 : 0 : case UNDERLINE_SINGLE: return "single";
935 : 0 : case UNDERLINE_DOUBLE: return "double";
936 : : case UNDERLINE_NONE:
937 : 0 : default: bHaveUnderline = false; return "none";
938 : : }
939 : : }
940 : :
941 : 0 : static const char* lcl_ToVerticalAlignmentRun( SvxEscapement eEscapement, bool& bHaveAlignment )
942 : : {
943 : 0 : bHaveAlignment = true;
944 [ # # # ]: 0 : switch( eEscapement )
945 : : {
946 : 0 : case SVX_ESCAPEMENT_SUPERSCRIPT: return "superscript";
947 : 0 : case SVX_ESCAPEMENT_SUBSCRIPT: return "subscript";
948 : : case SVX_ESCAPEMENT_OFF:
949 : 0 : default: bHaveAlignment = false; return "baseline";
950 : : }
951 : : }
952 : :
953 : 0 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteFontData( sax_fastparser::FSHelperPtr pStream, const XclFontData& rFontData, sal_Int32 nFontId )
954 : : {
955 : : bool bHaveUnderline, bHaveVertAlign;
956 [ # # ]: 0 : const char* pUnderline = lcl_GetUnderlineStyle( rFontData.GetScUnderline(), bHaveUnderline );
957 [ # # ]: 0 : const char* pVertAlign = lcl_ToVerticalAlignmentRun( rFontData.GetScEscapement(), bHaveVertAlign );
958 : :
959 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, nFontId, XclXmlUtils::ToOString( rFontData.maName ).getStr() );
960 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, XML_charset, rFontData.mnCharSet != 0 ? OString::valueOf( (sal_Int32) rFontData.mnCharSet ).getStr() : NULL );
[ # # ][ # # ]
961 [ # # ]: 0 : lcl_WriteValue( pStream, XML_family, OString::valueOf( (sal_Int32) rFontData.mnFamily ).getStr() );
962 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, XML_b, rFontData.mnWeight > 400 ? XclXmlUtils::ToPsz( rFontData.mnWeight > 400 ) : NULL );
963 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, XML_i, rFontData.mbItalic ? XclXmlUtils::ToPsz( rFontData.mbItalic ) : NULL );
964 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, XML_strike, rFontData.mbStrikeout ? XclXmlUtils::ToPsz( rFontData.mbStrikeout ) : NULL );
965 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, XML_outline, rFontData.mbOutline ? XclXmlUtils::ToPsz( rFontData.mbOutline ) : NULL );
966 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, XML_shadow, rFontData.mbShadow ? XclXmlUtils::ToPsz( rFontData.mbShadow ) : NULL );
967 : : // OOXTODO: lcl_WriteValue( rStream, XML_condense, ); // mac compatibility setting
968 : : // OOXTODO: lcl_WriteValue( rStream, XML_extend, ); // compatibility setting
969 [ # # ]: 0 : if( rFontData.maColor != Color( 0xFF, 0xFF, 0xFF, 0xFF ) )
970 : : pStream->singleElement( XML_color,
971 : : // OOXTODO: XML_auto, bool
972 : : // OOXTODO: XML_indexed, uint
973 : : XML_rgb, XclXmlUtils::ToOString( rFontData.maColor ).getStr(),
974 : : // OOXTODO: XML_theme, index into <clrScheme/>
975 : : // OOXTODO: XML_tint, double
976 [ # # ][ # # ]: 0 : FSEND );
977 [ # # ]: 0 : lcl_WriteValue( pStream, XML_sz, OString::valueOf( (double) (rFontData.mnHeight / 20.0) ).getStr() ); // Twips->Pt
978 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, XML_u, bHaveUnderline ? pUnderline : NULL );
979 [ # # ][ # # ]: 0 : lcl_WriteValue( pStream, XML_vertAlign, bHaveVertAlign ? pVertAlign : NULL );
980 : :
981 [ # # ]: 0 : return pStream;
982 : : }
983 : :
984 : :
985 : : // ============================================================================
986 : :
987 : 0 : XclExpXmlStream::XclExpXmlStream( const Reference< XComponentContext >& rCC )
988 : : : XmlFilterBase( rCC ),
989 [ # # ][ # # ]: 0 : mpRoot( NULL )
[ # # ]
990 : : {
991 : 0 : }
992 : :
993 : 0 : XclExpXmlStream::~XclExpXmlStream()
994 : : {
995 [ # # ]: 0 : }
996 : :
997 : 0 : sax_fastparser::FSHelperPtr& XclExpXmlStream::GetCurrentStream()
998 : : {
999 : : OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::GetCurrentStream - no current stream" );
1000 : 0 : return maStreams.top();
1001 : : }
1002 : :
1003 : 0 : void XclExpXmlStream::PushStream( sax_fastparser::FSHelperPtr aStream )
1004 : : {
1005 : 0 : maStreams.push( aStream );
1006 : 0 : }
1007 : :
1008 : 0 : void XclExpXmlStream::PopStream()
1009 : : {
1010 : : OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::PopStream - stack is empty!" );
1011 : 0 : maStreams.pop();
1012 : 0 : }
1013 : :
1014 : 0 : sax_fastparser::FSHelperPtr XclExpXmlStream::GetStreamForPath( const OUString& sPath )
1015 : : {
1016 [ # # ][ # # ]: 0 : if( maOpenedStreamMap.find( sPath ) == maOpenedStreamMap.end() )
1017 : 0 : return sax_fastparser::FSHelperPtr();
1018 : 0 : return maOpenedStreamMap[ sPath ].second;
1019 : : }
1020 : :
1021 : 0 : sax_fastparser::FSHelperPtr& XclExpXmlStream::WriteAttributes( sal_Int32 nAttribute, ... )
1022 : : {
1023 [ # # ]: 0 : sax_fastparser::FSHelperPtr& rStream = GetCurrentStream();
1024 : :
1025 : : va_list args;
1026 : 0 : va_start( args, nAttribute );
1027 : 0 : do {
1028 : 0 : const char* pValue = va_arg( args, const char* );
1029 [ # # ]: 0 : if( pValue )
1030 : : {
1031 : : rStream->write( " " )
1032 : : ->writeId( nAttribute )
1033 : : ->write( "=\"" )
1034 : : ->writeEscaped( pValue )
1035 [ # # ][ # # ]: 0 : ->write( "\"" );
[ # # ][ # # ]
[ # # ]
1036 : : }
1037 : :
1038 : 0 : nAttribute = va_arg( args, sal_Int32 );
1039 [ # # ]: 0 : if( nAttribute == FSEND )
1040 : 0 : break;
1041 : : } while( true );
1042 : 0 : va_end( args );
1043 : :
1044 : 0 : return rStream;
1045 : : }
1046 : 0 : sax_fastparser::FSHelperPtr XclExpXmlStream::CreateOutputStream (
1047 : : const OUString& sFullStream,
1048 : : const OUString& sRelativeStream,
1049 : : const Reference< XOutputStream >& xParentRelation,
1050 : : const char* sContentType,
1051 : : const char* sRelationshipType,
1052 : : OUString* pRelationshipId )
1053 : : {
1054 : 0 : OUString sRelationshipId;
1055 [ # # ]: 0 : if (xParentRelation.is())
1056 [ # # ]: 0 : sRelationshipId = addRelation( xParentRelation, OUString::createFromAscii( sRelationshipType), sRelativeStream );
1057 : : else
1058 [ # # ]: 0 : sRelationshipId = addRelation( OUString::createFromAscii( sRelationshipType ), sRelativeStream );
1059 : :
1060 [ # # ]: 0 : if( pRelationshipId )
1061 : 0 : *pRelationshipId = sRelationshipId;
1062 : :
1063 [ # # ]: 0 : sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
1064 : :
1065 [ # # ][ # # ]: 0 : maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );
[ # # ][ # # ]
1066 : :
1067 : 0 : return p;
1068 : : }
1069 : :
1070 : 0 : bool XclExpXmlStream::importDocument() throw()
1071 : : {
1072 : 0 : return false;
1073 : : }
1074 : :
1075 : 0 : oox::vml::Drawing* XclExpXmlStream::getVmlDrawing()
1076 : : {
1077 : 0 : return 0;
1078 : : }
1079 : :
1080 : 0 : const oox::drawingml::Theme* XclExpXmlStream::getCurrentTheme() const
1081 : : {
1082 : 0 : return 0;
1083 : : }
1084 : :
1085 : 0 : const oox::drawingml::table::TableStyleListPtr XclExpXmlStream::getTableStyles()
1086 : : {
1087 : 0 : return oox::drawingml::table::TableStyleListPtr();
1088 : : }
1089 : :
1090 : 0 : oox::drawingml::chart::ChartConverter* XclExpXmlStream::getChartConverter()
1091 : : {
1092 : : // DO NOT CALL
1093 : 0 : return NULL;
1094 : : }
1095 : :
1096 : 0 : ScDocShell* XclExpXmlStream::getDocShell()
1097 : : {
1098 [ # # ][ # # ]: 0 : Reference< XInterface > xModel( getModel(), UNO_QUERY );
1099 : :
1100 [ # # ][ # # ]: 0 : ScModelObj *pObj = dynamic_cast < ScModelObj* >( xModel.get() );
1101 : :
1102 [ # # ]: 0 : if ( pObj )
1103 [ # # ]: 0 : return static_cast < ScDocShell* >( pObj->GetEmbeddedObject() );
1104 : :
1105 : 0 : return 0;
1106 : : }
1107 : :
1108 : 0 : bool XclExpXmlStream::exportDocument() throw()
1109 : : {
1110 [ # # ]: 0 : ScDocShell* pShell = getDocShell();
1111 : 0 : ScDocument* pDoc = pShell->GetDocument();
1112 : : // NOTE: Don't use SotStorage or SvStream any more, and never call
1113 : : // SfxMedium::GetOutStream() anywhere in the xlsx export filter code!
1114 : : // Instead, write via XOutputStream instance.
1115 : 0 : SotStorageRef rStorage = static_cast<SotStorage*>(NULL);
1116 [ # # ]: 0 : XclExpObjList::ResetCounters();
1117 : :
1118 [ # # ][ # # ]: 0 : XclExpRootData aData( EXC_BIFF8, *pShell->GetMedium (), rStorage, *pDoc, RTL_TEXTENCODING_DONTKNOW );
1119 : 0 : aData.meOutput = EXC_OUTPUT_XML_2007;
1120 : 0 : aData.maXclMaxPos.Set( EXC_MAXCOL_XML_2007, EXC_MAXROW_XML_2007, EXC_MAXTAB_XML_2007 );
1121 [ # # ]: 0 : aData.maMaxPos.SetCol( ::std::min( aData.maScMaxPos.Col(), aData.maXclMaxPos.Col() ) );
1122 [ # # ]: 0 : aData.maMaxPos.SetRow( ::std::min( aData.maScMaxPos.Row(), aData.maXclMaxPos.Row() ) );
1123 [ # # ]: 0 : aData.maMaxPos.SetTab( ::std::min( aData.maScMaxPos.Tab(), aData.maXclMaxPos.Tab() ) );
1124 : :
1125 [ # # ]: 0 : XclExpRoot aRoot( aData );
1126 : :
1127 : 0 : mpRoot = &aRoot;
1128 [ # # ]: 0 : aRoot.GetOldRoot().pER = &aRoot;
1129 [ # # ]: 0 : aRoot.GetOldRoot().eDateiTyp = Biff8;
1130 : : // Get the viewsettings before processing
1131 [ # # ][ # # ]: 0 : if( pShell->GetViewData() )
1132 [ # # ][ # # ]: 0 : pShell->GetViewData()->WriteExtOptions( mpRoot->GetExtDocOptions() );
[ # # ]
1133 : :
1134 [ # # ]: 0 : OUString const workbook = CREATE_OUSTRING( "xl/workbook.xml" );
1135 : : PushStream( CreateOutputStream( workbook, workbook,
1136 : : Reference <XOutputStream>(),
1137 : : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
1138 [ # # ][ # # ]: 0 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) );
[ # # ]
1139 : :
1140 : : // destruct at the end of the block
1141 : : {
1142 [ # # ]: 0 : ExcDocument aDocRoot( aRoot );
1143 [ # # ]: 0 : aDocRoot.ReadDoc();
1144 [ # # ][ # # ]: 0 : aDocRoot.WriteXml( *this );
1145 : : }
1146 : :
1147 : 0 : mpRoot = NULL;
1148 [ # # ][ # # ]: 0 : return true;
[ # # ]
1149 : : }
1150 : :
1151 : : //////////////////////////////////////////////////////////////////////////
1152 : : // UNO stuff so that the filter is registered
1153 : : //////////////////////////////////////////////////////////////////////////
1154 : :
1155 : : #define IMPL_NAME "com.sun.star.comp.oox.ExcelFilterExport"
1156 : :
1157 : 6 : OUString XlsxExport_getImplementationName()
1158 : : {
1159 : 6 : return OUString( RTL_CONSTASCII_USTRINGPARAM( IMPL_NAME ) );
1160 : : }
1161 : :
1162 : 0 : ::oox::ole::VbaProject* XclExpXmlStream::implCreateVbaProject() const
1163 : : {
1164 [ # # ][ # # ]: 0 : return new ::oox::xls::ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
1165 : : }
1166 : :
1167 : 0 : OUString XclExpXmlStream::implGetImplementationName() const
1168 : : {
1169 : 0 : return CREATE_OUSTRING( "TODO" );
1170 : : }
1171 : :
1172 : :
1173 : 0 : Sequence< OUString > SAL_CALL XlsxExport_getSupportedServiceNames() throw()
1174 : : {
1175 [ # # ]: 0 : const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.ExportFilter" ) );
1176 [ # # ]: 0 : const Sequence< OUString > aSeq( &aServiceName, 1 );
1177 : 0 : return aSeq;
1178 : : }
1179 : :
1180 : 0 : Reference< XInterface > SAL_CALL XlsxExport_createInstance(const Reference< XComponentContext > & rCC ) throw( Exception )
1181 : : {
1182 [ # # ]: 0 : return (cppu::OWeakObject*) new XclExpXmlStream( rCC );
1183 : : }
1184 : :
1185 : : namespace oox { namespace xls {
1186 : : OUString SAL_CALL ExcelFilter_getImplementationName() throw();
1187 : : Sequence< OUString > SAL_CALL ExcelFilter_getSupportedServiceNames() throw();
1188 : : Reference< XInterface > SAL_CALL ExcelFilter_createInstance(
1189 : : const Reference< XComponentContext >& rxContext ) throw( Exception );
1190 : : } }
1191 : :
1192 : : #ifdef __cplusplus
1193 : : extern "C"
1194 : : {
1195 : : #endif
1196 : :
1197 : : // ------------------------
1198 : : // - component_getFactory -
1199 : : // ------------------------
1200 : : ::cppu::ImplementationEntry entries [] =
1201 : : {
1202 : : {
1203 : : XlsxExport_createInstance, XlsxExport_getImplementationName,
1204 : : XlsxExport_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
1205 : : 0, 0
1206 : : },
1207 : : {
1208 : : oox::xls::ExcelFilter_createInstance, oox::xls::ExcelFilter_getImplementationName,
1209 : : oox::xls::ExcelFilter_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
1210 : : 0, 0
1211 : : },
1212 : : { 0, 0, 0, 0, 0, 0 }
1213 : : };
1214 : :
1215 : 6 : SAL_DLLPUBLIC_EXPORT void* SAL_CALL scfilt_component_getFactory( const sal_Char* pImplName, XMultiServiceFactory* pServiceManager, XRegistryKey* pRegistryKey )
1216 : : {
1217 : 6 : return ::cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, entries );
1218 : :
1219 : : }
1220 : :
1221 : : #ifdef __cplusplus
1222 [ + - ][ + - ]: 24 : }
1223 : : #endif
1224 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|