LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xestream.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 370 572 64.7 %
Date: 2015-06-13 12:38:46 Functions: 63 97 64.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11