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

Generated by: LCOV version 1.10