LCOV - code coverage report
Current view: top level - package/source/zippackage - ZipPackageFolder.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 255 380 67.1 %
Date: 2012-08-25 Functions: 21 28 75.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 260 711 36.6 %

           Branch data     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 <string.h>
      21                 :            : 
      22                 :            : #include <ZipPackageFolder.hxx>
      23                 :            : #include <ZipFile.hxx>
      24                 :            : #include <ZipOutputStream.hxx>
      25                 :            : #include <ZipPackageStream.hxx>
      26                 :            : #include <PackageConstants.hxx>
      27                 :            : #include <ZipPackageFolderEnumeration.hxx>
      28                 :            : #include <com/sun/star/packages/zip/ZipConstants.hpp>
      29                 :            : #include <com/sun/star/embed/StorageFormats.hpp>
      30                 :            : #include <osl/diagnose.h>
      31                 :            : #include <osl/time.h>
      32                 :            : #include <rtl/digest.h>
      33                 :            : #include <ContentInfo.hxx>
      34                 :            : #include <com/sun/star/beans/PropertyValue.hpp>
      35                 :            : #include <com/sun/star/io/XSeekable.hpp>
      36                 :            : #include <EncryptedDataHeader.hxx>
      37                 :            : #include <rtl/random.h>
      38                 :            : #include <rtl/instance.hxx>
      39                 :            : #include <memory>
      40                 :            : 
      41                 :            : using namespace com::sun::star;
      42                 :            : using namespace com::sun::star::packages::zip::ZipConstants;
      43                 :            : using namespace com::sun::star::packages::zip;
      44                 :            : using namespace com::sun::star::packages;
      45                 :            : using namespace com::sun::star::container;
      46                 :            : using namespace com::sun::star::beans;
      47                 :            : using namespace com::sun::star::lang;
      48                 :            : using namespace com::sun::star::io;
      49                 :            : using namespace cppu;
      50                 :            : using namespace std;
      51                 :            : using namespace ::com::sun::star;
      52                 :            : 
      53                 :            : namespace { struct lcl_CachedImplId : public rtl::Static< uno::Sequence < sal_Int8 >, lcl_CachedImplId > {}; }
      54                 :            : 
      55                 :      43074 : ZipPackageFolder::ZipPackageFolder ( const uno::Reference< XMultiServiceFactory >& xFactory,
      56                 :            :                                      sal_Int32 nFormat,
      57                 :            :                                      sal_Bool bAllowRemoveOnInsert )
      58                 :            : : m_xFactory( xFactory )
      59         [ +  - ]:      43074 : , m_nFormat( nFormat )
      60                 :            : {
      61                 :            :     OSL_ENSURE( m_xFactory.is(), "No factory is provided to the package folder!" );
      62                 :            : 
      63                 :      43074 :     this->mbAllowRemoveOnInsert = bAllowRemoveOnInsert;
      64                 :            : 
      65                 :      43074 :     SetFolder ( sal_True );
      66                 :      43074 :     aEntry.nVersion     = -1;
      67                 :      43074 :     aEntry.nFlag        = 0;
      68                 :      43074 :     aEntry.nMethod      = STORED;
      69                 :      43074 :     aEntry.nTime        = -1;
      70                 :      43074 :     aEntry.nCrc         = 0;
      71                 :      43074 :     aEntry.nCompressedSize  = 0;
      72                 :      43074 :     aEntry.nSize        = 0;
      73                 :      43074 :     aEntry.nOffset      = -1;
      74         [ +  - ]:      43074 :     uno::Sequence < sal_Int8 > &rCachedImplId = lcl_CachedImplId::get();
      75         [ +  + ]:      43074 :     if ( !rCachedImplId.getLength() )
      76 [ +  - ][ +  - ]:        187 :         rCachedImplId = getImplementationId();
                 [ +  - ]
      77                 :      43074 : }
      78                 :            : 
      79                 :            : 
      80         [ +  - ]:      41019 : ZipPackageFolder::~ZipPackageFolder()
      81                 :            : {
      82         [ -  + ]:      82038 : }
      83                 :            : 
      84                 :       5403 : sal_Bool ZipPackageFolder::LookForUnexpectedODF12Streams( const OUString& aPath )
      85                 :            : {
      86                 :       5403 :     sal_Bool bHasUnexpected = sal_False;
      87                 :            : 
      88 [ +  - ][ +  - ]:      26528 :     for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end();
           [ +  -  +  + ]
                 [ +  + ]
      89                 :      13264 :           !bHasUnexpected && aCI != aEnd;
      90                 :            :           ++aCI)
      91                 :            :     {
      92         [ +  - ]:       7861 :         const OUString &rShortName = (*aCI).first;
      93         [ +  - ]:       7861 :         const ContentInfo &rInfo = *(*aCI).second;
      94                 :            : 
      95         [ +  + ]:       7861 :         if ( rInfo.bFolder )
      96                 :            :         {
      97         [ -  + ]:       4826 :             if ( aPath == "META-INF/" )
      98                 :            :             {
      99                 :            :                 // META-INF is not allowed to contain subfolders
     100                 :          0 :                 bHasUnexpected = sal_True;
     101                 :            :             }
     102                 :            :             else
     103                 :            :             {
     104                 :       4826 :                 OUString sOwnPath = aPath + rShortName + "/";
     105         [ +  - ]:       4826 :                 bHasUnexpected = rInfo.pFolder->LookForUnexpectedODF12Streams( sOwnPath );
     106                 :            :             }
     107                 :            :         }
     108                 :            :         else
     109                 :            :         {
     110         [ -  + ]:       3035 :             if ( aPath == "META-INF/" )
     111                 :            :             {
     112   [ #  #  #  # ]:          0 :                 if ( rShortName != "manifest.xml"
                 [ #  # ]
     113                 :          0 :                   && rShortName.indexOf( "signatures" ) == -1 )
     114                 :            :                 {
     115                 :            :                     // a stream from META-INF with unexpected name
     116                 :          0 :                     bHasUnexpected = sal_True;
     117                 :            :                 }
     118                 :            : 
     119                 :            :                 // streams from META-INF with expected names are allowed not to be registered in manifest.xml
     120                 :            :             }
     121         [ -  + ]:       3035 :             else if ( !rInfo.pStream->IsFromManifest() )
     122                 :            :             {
     123                 :            :                 // the stream is not in META-INF and ist notregistered in manifest.xml,
     124                 :            :                 // check whether it is an internal part of the package format
     125 [ #  # ][ #  # ]:          0 :                 if ( !aPath.isEmpty() || rShortName != "mimetype" )
                 [ #  # ]
     126                 :            :                 {
     127                 :            :                     // if it is not "mimetype" from the root it is not a part of the package
     128                 :          0 :                     bHasUnexpected = sal_True;
     129                 :            :                 }
     130                 :            :             }
     131                 :            :         }
     132                 :            :     }
     133                 :            : 
     134                 :       5403 :     return bHasUnexpected;
     135                 :            : }
     136                 :            : 
     137                 :       2469 : void ZipPackageFolder::setChildStreamsTypeByExtension( const beans::StringPair& aPair )
     138                 :            : {
     139                 :       2469 :     OUString aExt;
     140         [ -  + ]:       2469 :     if ( aPair.First.toChar() == (sal_Unicode)'.' )
     141                 :          0 :         aExt = aPair.First;
     142                 :            :     else
     143                 :       2469 :         aExt = "." + aPair.First;
     144                 :            : 
     145 [ +  - ][ +  - ]:       9527 :     for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end();
                 [ +  + ]
     146                 :            :           aCI != aEnd;
     147                 :            :           ++aCI)
     148                 :            :     {
     149         [ +  - ]:       7058 :         const OUString &rShortName = (*aCI).first;
     150         [ +  - ]:       7058 :         const ContentInfo &rInfo = *(*aCI).second;
     151                 :            : 
     152         [ +  + ]:       7058 :         if ( rInfo.bFolder )
     153         [ +  - ]:       2092 :             rInfo.pFolder->setChildStreamsTypeByExtension( aPair );
     154                 :            :         else
     155                 :            :         {
     156                 :       4966 :             sal_Int32 nPathLength = rShortName.getLength();
     157                 :       4966 :             sal_Int32 nExtLength = aExt.getLength();
     158 [ +  + ][ +  + ]:       4966 :             if ( nPathLength >= nExtLength && rShortName.match( aExt, nPathLength - nExtLength ) )
                 [ +  - ]
     159                 :       2186 :                 rInfo.pStream->SetMediaType( aPair.Second );
     160                 :            :         }
     161                 :       2469 :     }
     162                 :       2469 : }
     163                 :            : 
     164                 :       3006 : void ZipPackageFolder::copyZipEntry( ZipEntry &rDest, const ZipEntry &rSource)
     165                 :            : {
     166                 :       3006 :       rDest.nVersion            = rSource.nVersion;
     167                 :       3006 :     rDest.nFlag             = rSource.nFlag;
     168                 :       3006 :     rDest.nMethod           = rSource.nMethod;
     169                 :       3006 :     rDest.nTime             = rSource.nTime;
     170                 :       3006 :     rDest.nCrc              = rSource.nCrc;
     171                 :       3006 :     rDest.nCompressedSize   = rSource.nCompressedSize;
     172                 :       3006 :     rDest.nSize             = rSource.nSize;
     173                 :       3006 :     rDest.nOffset           = rSource.nOffset;
     174                 :       3006 :     rDest.sPath             = rSource.sPath;
     175                 :       3006 :     rDest.nPathLen          = rSource.nPathLen;
     176                 :       3006 :     rDest.nExtraLen         = rSource.nExtraLen;
     177                 :       3006 : }
     178                 :            : 
     179                 :      18860 : const ::com::sun::star::uno::Sequence < sal_Int8 >& ZipPackageFolder::static_getImplementationId()
     180                 :            : {
     181                 :      18860 :     return lcl_CachedImplId::get();
     182                 :            : }
     183                 :            : 
     184                 :            :     // XNameContainer
     185                 :       4033 : void SAL_CALL ZipPackageFolder::insertByName( const OUString& aName, const uno::Any& aElement )
     186                 :            :         throw(IllegalArgumentException, ElementExistException, WrappedTargetException, uno::RuntimeException)
     187                 :            : {
     188         [ -  + ]:       4033 :     if (hasByName(aName))
     189         [ #  # ]:          0 :         throw ElementExistException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     190                 :            :     else
     191                 :            :     {
     192                 :       4033 :         uno::Reference < XUnoTunnel > xRef;
     193         [ +  - ]:       4033 :         aElement >>= xRef;
     194 [ +  - ][ +  - ]:       4033 :         if ( (  aElement >>= xRef ) )
     195                 :            :         {
     196                 :            :             sal_Int64 nTest;
     197                 :            :             ZipPackageEntry *pEntry;
     198 [ +  - ][ +  - ]:       4033 :             if ( ( nTest = xRef->getSomething ( ZipPackageFolder::static_getImplementationId() ) ) != 0 )
         [ +  - ][ +  + ]
     199                 :            :             {
     200                 :        736 :                 ZipPackageFolder *pFolder = reinterpret_cast < ZipPackageFolder * > ( nTest );
     201                 :        736 :                 pEntry = static_cast < ZipPackageEntry * > ( pFolder );
     202                 :            :             }
     203 [ +  - ][ +  - ]:       3297 :             else if ( ( nTest = xRef->getSomething ( ZipPackageStream::static_getImplementationId() ) ) != 0 )
         [ +  - ][ +  - ]
     204                 :            :             {
     205                 :       3297 :                 ZipPackageStream *pStream = reinterpret_cast < ZipPackageStream * > ( nTest );
     206                 :       3297 :                 pEntry = static_cast < ZipPackageEntry * > ( pStream );
     207                 :            :             }
     208                 :            :             else
     209         [ #  # ]:          0 :                 throw IllegalArgumentException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 );
     210                 :            : 
     211 [ +  - ][ +  + ]:       4033 :             if (pEntry->getName() != aName )
     212         [ +  - ]:       4031 :                 pEntry->setName (aName);
     213         [ +  - ]:       4033 :             doInsertByName ( pEntry, sal_True );
     214                 :            :         }
     215                 :            :         else
     216         [ #  # ]:       4033 :             throw IllegalArgumentException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >(), 0 );
     217                 :            :     }
     218                 :       4033 : }
     219                 :       1821 : void SAL_CALL ZipPackageFolder::removeByName( const OUString& Name )
     220                 :            :         throw(NoSuchElementException, WrappedTargetException, uno::RuntimeException)
     221                 :            : {
     222         [ +  - ]:       1821 :     ContentHash::iterator aIter = maContents.find ( Name );
     223 [ +  - ][ -  + ]:       1821 :     if ( aIter == maContents.end() )
     224         [ #  # ]:          0 :         throw NoSuchElementException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     225         [ +  - ]:       1821 :     maContents.erase( aIter );
     226                 :       1821 : }
     227                 :            :     // XEnumerationAccess
     228                 :      20404 : uno::Reference< XEnumeration > SAL_CALL ZipPackageFolder::createEnumeration(  )
     229                 :            :         throw(uno::RuntimeException)
     230                 :            : {
     231 [ +  - ][ +  - ]:      20404 :     return uno::Reference < XEnumeration> (new ZipPackageFolderEnumeration(maContents));
     232                 :            : }
     233                 :            :     // XElementAccess
     234                 :          0 : uno::Type SAL_CALL ZipPackageFolder::getElementType(  )
     235                 :            :         throw(uno::RuntimeException)
     236                 :            : {
     237                 :          0 :     return ::getCppuType ((const uno::Reference< XUnoTunnel > *) 0);
     238                 :            : }
     239                 :          0 : sal_Bool SAL_CALL ZipPackageFolder::hasElements(  )
     240                 :            :         throw(uno::RuntimeException)
     241                 :            : {
     242                 :          0 :     return maContents.size() > 0;
     243                 :            : }
     244                 :            :     // XNameAccess
     245                 :      21658 : ContentInfo& ZipPackageFolder::doGetByName( const OUString& aName )
     246                 :            :     throw(NoSuchElementException, WrappedTargetException, uno::RuntimeException)
     247                 :            : {
     248         [ +  - ]:      21658 :     ContentHash::iterator aIter = maContents.find ( aName );
     249 [ +  - ][ -  + ]:      21658 :     if ( aIter == maContents.end())
     250         [ #  # ]:          0 :         throw NoSuchElementException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     251         [ +  - ]:      21658 :     return *(*aIter).second;
     252                 :            : }
     253                 :      15827 : uno::Any SAL_CALL ZipPackageFolder::getByName( const OUString& aName )
     254                 :            :     throw(NoSuchElementException, WrappedTargetException, uno::RuntimeException)
     255                 :            : {
     256                 :      15827 :     return uno::makeAny ( doGetByName ( aName ).xTunnel );
     257                 :            : }
     258                 :          0 : uno::Sequence< OUString > SAL_CALL ZipPackageFolder::getElementNames(  )
     259                 :            :         throw(uno::RuntimeException)
     260                 :            : {
     261                 :          0 :     sal_uInt32 i=0, nSize = maContents.size();
     262                 :          0 :     uno::Sequence < OUString > aSequence ( nSize );
     263 [ #  # ][ #  # ]:          0 :     for ( ContentHash::const_iterator aIterator = maContents.begin(), aEnd = maContents.end();
                 [ #  # ]
     264                 :            :           aIterator != aEnd;
     265                 :            :           ++i, ++aIterator)
     266 [ #  # ][ #  # ]:          0 :         aSequence[i] = (*aIterator).first;
     267                 :          0 :     return aSequence;
     268                 :            : }
     269                 :      62954 : sal_Bool SAL_CALL ZipPackageFolder::hasByName( const OUString& aName )
     270                 :            :     throw(uno::RuntimeException)
     271                 :            : {
     272         [ +  - ]:      62954 :     return maContents.find ( aName ) != maContents.end ();
     273                 :            : }
     274                 :            :     // XNameReplace
     275                 :          0 : void SAL_CALL ZipPackageFolder::replaceByName( const OUString& aName, const uno::Any& aElement )
     276                 :            :         throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, uno::RuntimeException)
     277                 :            : {
     278         [ #  # ]:          0 :     if ( hasByName( aName ) )
     279                 :          0 :         removeByName( aName );
     280                 :            :     else
     281         [ #  # ]:          0 :         throw NoSuchElementException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     282                 :          0 :     insertByName(aName, aElement);
     283                 :          0 : }
     284                 :            : 
     285                 :         76 : static void ImplSetStoredData( ZipEntry & rEntry, uno::Reference< XInputStream> & rStream )
     286                 :            : {
     287                 :            :     // It's very annoying that we have to do this, but lots of zip packages
     288                 :            :     // don't allow data descriptors for STORED streams, meaning we have to
     289                 :            :     // know the size and CRC32 of uncompressed streams before we actually
     290                 :            :     // write them !
     291         [ +  - ]:         76 :     CRC32 aCRC32;
     292                 :         76 :     rEntry.nMethod = STORED;
     293         [ +  - ]:         76 :     rEntry.nCompressedSize = rEntry.nSize = aCRC32.updateStream ( rStream );
     294 [ +  - ][ +  - ]:         76 :     rEntry.nCrc = aCRC32.getValue();
     295                 :         76 : }
     296                 :            : 
     297                 :       2250 : bool ZipPackageFolder::saveChild( const OUString &rShortName, const ContentInfo &rInfo, OUString &rPath, std::vector < uno::Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool &rRandomPool)
     298                 :            : {
     299                 :       2250 :     bool bSuccess = true;
     300                 :            : 
     301                 :       2250 :     const OUString sMediaTypeProperty ("MediaType");
     302                 :       2250 :     const OUString sVersionProperty ("Version");
     303                 :       2250 :     const OUString sFullPathProperty ("FullPath");
     304                 :       2250 :     const OUString sInitialisationVectorProperty ("InitialisationVector");
     305                 :       2250 :     const OUString sSaltProperty ("Salt");
     306                 :       2250 :     const OUString sIterationCountProperty ("IterationCount");
     307                 :       2250 :     const OUString sSizeProperty ("Size");
     308                 :       2250 :     const OUString sDigestProperty ("Digest");
     309                 :       2250 :     const OUString sEncryptionAlgProperty    ("EncryptionAlgorithm");
     310                 :       2250 :     const OUString sStartKeyAlgProperty  ("StartKeyAlgorithm");
     311                 :       2250 :     const OUString sDigestAlgProperty    ("DigestAlgorithm");
     312                 :       2250 :     const OUString  sDerivedKeySizeProperty  ("DerivedKeySize");
     313                 :            : 
     314         [ +  - ]:       2250 :     uno::Sequence < PropertyValue > aPropSet (PKG_SIZE_NOENCR_MNFST);
     315                 :            : 
     316                 :            :     OSL_ENSURE( ( rInfo.bFolder && rInfo.pFolder ) || ( !rInfo.bFolder && rInfo.pStream ), "A valid child object is expected!" );
     317         [ +  + ]:       2250 :     if ( rInfo.bFolder )
     318                 :            :     {
     319                 :        912 :         OUString sTempName = rPath + rShortName + "/";
     320                 :            : 
     321         [ +  + ]:        912 :         if ( !rInfo.pFolder->GetMediaType().isEmpty() )
     322                 :            :         {
     323         [ +  - ]:         40 :             aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
     324 [ +  - ][ +  - ]:         40 :             aPropSet[PKG_MNFST_MEDIATYPE].Value <<= rInfo.pFolder->GetMediaType();
     325         [ +  - ]:         40 :             aPropSet[PKG_MNFST_VERSION].Name = sVersionProperty;
     326 [ +  - ][ +  - ]:         40 :             aPropSet[PKG_MNFST_VERSION].Value <<= rInfo.pFolder->GetVersion();
     327         [ +  - ]:         40 :             aPropSet[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
     328 [ +  - ][ +  - ]:         40 :             aPropSet[PKG_MNFST_FULLPATH].Value <<= sTempName;
     329                 :            :         }
     330                 :            :         else
     331         [ +  - ]:        872 :             aPropSet.realloc( 0 );
     332                 :            : 
     333         [ +  - ]:        912 :         rInfo.pFolder->saveContents( sTempName, rManList, rZipOut, rEncryptionKey, rRandomPool);
     334                 :            :     }
     335                 :            :     else
     336                 :            :     {
     337                 :            :         // if pTempEntry is necessary, it will be released and passed to the ZipOutputStream
     338                 :            :         // and be deleted in the ZipOutputStream destructor
     339         [ +  - ]:       1338 :         auto_ptr < ZipEntry > pAutoTempEntry ( new ZipEntry );
     340                 :       1338 :         ZipEntry* pTempEntry = pAutoTempEntry.get();
     341                 :            : 
     342                 :            :         // In case the entry we are reading is also the entry we are writing, we will
     343                 :            :         // store the ZipEntry data in pTempEntry
     344                 :            : 
     345                 :       1338 :         ZipPackageFolder::copyZipEntry ( *pTempEntry, rInfo.pStream->aEntry );
     346                 :       1338 :         pTempEntry->sPath = rPath + rShortName;
     347         [ +  - ]:       1338 :         pTempEntry->nPathLen = (sal_Int16)( OUStringToOString( pTempEntry->sPath, RTL_TEXTENCODING_UTF8 ).getLength() );
     348                 :            : 
     349 [ +  - ][ -  + ]:       1338 :         sal_Bool bToBeEncrypted = rInfo.pStream->IsToBeEncrypted() && (rEncryptionKey.getLength() || rInfo.pStream->HasOwnKey());
                 [ +  + ]
     350         [ +  - ]:       1338 :         sal_Bool bToBeCompressed = bToBeEncrypted ? sal_True : rInfo.pStream->IsToBeCompressed();
     351                 :            : 
     352         [ +  - ]:       1338 :         aPropSet[PKG_MNFST_MEDIATYPE].Name = sMediaTypeProperty;
     353 [ +  - ][ +  - ]:       1338 :         aPropSet[PKG_MNFST_MEDIATYPE].Value <<= rInfo.pStream->GetMediaType( );
     354         [ +  - ]:       1338 :         aPropSet[PKG_MNFST_VERSION].Name = sVersionProperty;
     355 [ +  - ][ +  - ]:       1338 :         aPropSet[PKG_MNFST_VERSION].Value <<= OUString(); // no version is stored for streams currently
     356         [ +  - ]:       1338 :         aPropSet[PKG_MNFST_FULLPATH].Name = sFullPathProperty;
     357 [ +  - ][ +  - ]:       1338 :         aPropSet[PKG_MNFST_FULLPATH].Value <<= pTempEntry->sPath;
     358                 :            : 
     359                 :            : 
     360                 :            :         OSL_ENSURE( rInfo.pStream->GetStreamMode() != PACKAGE_STREAM_NOTSET, "Unacceptable ZipPackageStream mode!" );
     361                 :            : 
     362                 :       1338 :         sal_Bool bRawStream = sal_False;
     363         [ +  + ]:       1338 :         if ( rInfo.pStream->GetStreamMode() == PACKAGE_STREAM_DETECT )
     364         [ +  - ]:         62 :             bRawStream = rInfo.pStream->ParsePackageRawStream();
     365         [ -  + ]:       1276 :         else if ( rInfo.pStream->GetStreamMode() == PACKAGE_STREAM_RAW )
     366                 :          0 :             bRawStream = sal_True;
     367                 :            : 
     368                 :       1338 :         sal_Bool bTransportOwnEncrStreamAsRaw = sal_False;
     369                 :            :         // During the storing the original size of the stream can be changed
     370                 :            :         // TODO/LATER: get rid of this hack
     371         [ -  + ]:       1338 :         sal_Int32 nOwnStreamOrigSize = bRawStream ? rInfo.pStream->GetMagicalHackSize() : rInfo.pStream->getSize();
     372                 :            : 
     373                 :       1338 :         sal_Bool bUseNonSeekableAccess = sal_False;
     374                 :       1338 :         uno::Reference < XInputStream > xStream;
     375 [ +  - ][ +  - ]:       1338 :         if ( !rInfo.pStream->IsPackageMember() && !bRawStream && !bToBeEncrypted && bToBeCompressed )
         [ +  + ][ +  + ]
                 [ +  + ]
     376                 :            :         {
     377                 :            :             // the stream is not a package member, not a raw stream,
     378                 :            :             // it should not be encrypted and it should be compressed,
     379                 :            :             // in this case nonseekable access can be used
     380                 :            : 
     381 [ +  - ][ +  - ]:       1106 :             xStream = rInfo.pStream->GetOwnStreamNoWrap();
     382         [ +  - ]:       1106 :             uno::Reference < XSeekable > xSeek ( xStream, uno::UNO_QUERY );
     383                 :            : 
     384 [ +  - ][ -  + ]:       1106 :             bUseNonSeekableAccess = ( xStream.is() && !xSeek.is() );
     385                 :            :         }
     386                 :            : 
     387         [ +  - ]:       1338 :         if ( !bUseNonSeekableAccess )
     388                 :            :         {
     389 [ +  - ][ +  - ]:       1338 :             xStream = rInfo.pStream->getRawData();
                 [ #  # ]
     390                 :            : 
     391         [ -  + ]:       1338 :             if ( !xStream.is() )
     392                 :            :             {
     393                 :            :                 OSL_FAIL( "ZipPackageStream didn't have a stream associated with it, skipping!" );
     394                 :          0 :                 bSuccess = false;
     395                 :          0 :                 return bSuccess;
     396                 :            :             }
     397                 :            : 
     398         [ +  - ]:       1338 :             uno::Reference < XSeekable > xSeek ( xStream, uno::UNO_QUERY );
     399                 :            :             try
     400                 :            :             {
     401         [ +  + ]:       1338 :                 if ( xSeek.is() )
     402                 :            :                 {
     403                 :            :                     // If the stream is a raw one, then we should be positioned
     404                 :            :                     // at the beginning of the actual data
     405 [ +  + ][ -  + ]:       1182 :                     if ( !bToBeCompressed || bRawStream )
     406                 :            :                     {
     407                 :            :                         // The raw stream can neither be encrypted nor connected
     408                 :            :                         OSL_ENSURE( !bRawStream || !(bToBeCompressed || bToBeEncrypted), "The stream is already encrypted!\n" );
     409 [ +  - ][ -  + ]:         76 :                         xSeek->seek ( bRawStream ? rInfo.pStream->GetMagicalHackPos() : 0 );
                 [ +  - ]
     410         [ +  - ]:         76 :                         ImplSetStoredData ( *pTempEntry, xStream );
     411                 :            : 
     412                 :            :                         // TODO/LATER: Get rid of hacks related to switching of Flag Method and Size properties!
     413                 :            :                     }
     414         [ -  + ]:       1106 :                     else if ( bToBeEncrypted )
     415                 :            :                     {
     416                 :            :                         // this is the correct original size
     417 [ #  # ][ #  # ]:          0 :                         pTempEntry->nSize = static_cast < sal_Int32 > ( xSeek->getLength() );
     418                 :          0 :                         nOwnStreamOrigSize = pTempEntry->nSize;
     419                 :            :                     }
     420                 :            : 
     421 [ +  - ][ +  - ]:       1182 :                     xSeek->seek ( 0 );
     422                 :            :                 }
     423                 :            :                 else
     424                 :            :                 {
     425                 :            :                     // Okay, we don't have an xSeekable stream. This is possibly bad.
     426                 :            :                     // check if it's one of our own streams, if it is then we know that
     427                 :            :                     // each time we ask for it we'll get a new stream that will be
     428                 :            :                     // at position zero...otherwise, assert and skip this stream...
     429         [ +  - ]:        156 :                     if ( rInfo.pStream->IsPackageMember() )
     430                 :            :                     {
     431                 :            :                         // if the password has been changed than the stream should not be package member any more
     432 [ -  + ][ #  # ]:        156 :                         if ( rInfo.pStream->IsEncrypted() && rInfo.pStream->IsToBeEncrypted() )
                 [ -  + ]
     433                 :            :                         {
     434                 :            :                             // Should be handled close to the raw stream handling
     435                 :          0 :                             bTransportOwnEncrStreamAsRaw = sal_True;
     436                 :          0 :                             pTempEntry->nMethod = STORED;
     437                 :            : 
     438                 :            :                             // TODO/LATER: get rid of this situation
     439                 :            :                             // this size should be different from the one that will be stored in manifest.xml
     440                 :            :                             // it is used in storing algorithms and after storing the correct size will be set
     441                 :          0 :                             pTempEntry->nSize = pTempEntry->nCompressedSize;
     442                 :            :                         }
     443                 :            :                     }
     444                 :            :                     else
     445                 :            :                     {
     446                 :          0 :                         bSuccess = false;
     447                 :          0 :                         return bSuccess;
     448                 :            :                     }
     449                 :            :                 }
     450                 :            :             }
     451         [ #  # ]:          0 :             catch ( uno::Exception& )
     452                 :            :             {
     453                 :          0 :                 bSuccess = false;
     454                 :          0 :                 return bSuccess;
     455                 :            :             }
     456                 :            : 
     457 [ +  - ][ +  - ]:       1338 :             if ( bToBeEncrypted || bRawStream || bTransportOwnEncrStreamAsRaw )
                 [ -  + ]
     458                 :            :             {
     459 [ #  # ][ #  # ]:          0 :                 if ( bToBeEncrypted && !bTransportOwnEncrStreamAsRaw )
     460                 :            :                 {
     461 [ #  # ][ #  # ]:          0 :                     uno::Sequence < sal_Int8 > aSalt( 16 ), aVector( rInfo.pStream->GetBlockSize() );
                 [ #  # ]
     462         [ #  # ]:          0 :                     rtl_random_getBytes ( rRandomPool, aSalt.getArray(), 16 );
     463         [ #  # ]:          0 :                     rtl_random_getBytes ( rRandomPool, aVector.getArray(), aVector.getLength() );
     464                 :          0 :                     sal_Int32 nIterationCount = 1024;
     465                 :            : 
     466         [ #  # ]:          0 :                     if ( !rInfo.pStream->HasOwnKey() )
     467         [ #  # ]:          0 :                         rInfo.pStream->setKey ( rEncryptionKey );
     468                 :            : 
     469         [ #  # ]:          0 :                     rInfo.pStream->setInitialisationVector ( aVector );
     470         [ #  # ]:          0 :                     rInfo.pStream->setSalt ( aSalt );
     471 [ #  # ][ #  # ]:          0 :                     rInfo.pStream->setIterationCount ( nIterationCount );
                 [ #  # ]
     472                 :            :                 }
     473                 :            : 
     474                 :            :                 // last property is digest, which is inserted later if we didn't have
     475                 :            :                 // a magic header
     476         [ #  # ]:          0 :                 aPropSet.realloc(PKG_SIZE_ENCR_MNFST);
     477                 :            : 
     478         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_INIVECTOR].Name = sInitialisationVectorProperty;
     479 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_INIVECTOR].Value <<= rInfo.pStream->getInitialisationVector();
         [ #  # ][ #  # ]
     480         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_SALT].Name = sSaltProperty;
     481 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_SALT].Value <<= rInfo.pStream->getSalt();
         [ #  # ][ #  # ]
     482         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_ITERATION].Name = sIterationCountProperty;
     483 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_ITERATION].Value <<= rInfo.pStream->getIterationCount ();
                 [ #  # ]
     484                 :            : 
     485                 :            :                 // Need to store the uncompressed size in the manifest
     486                 :            :                 OSL_ENSURE( nOwnStreamOrigSize >= 0, "The stream size was not correctly initialized!\n" );
     487         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_UCOMPSIZE].Name = sSizeProperty;
     488 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_UCOMPSIZE].Value <<= nOwnStreamOrigSize;
     489                 :            : 
     490 [ #  # ][ #  # ]:          0 :                 if ( bRawStream || bTransportOwnEncrStreamAsRaw )
     491                 :            :                 {
     492         [ #  # ]:          0 :                     ::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData();
     493         [ #  # ]:          0 :                     if ( !xEncData.is() )
     494         [ #  # ]:          0 :                         throw uno::RuntimeException();
     495                 :            : 
     496         [ #  # ]:          0 :                     aPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty;
     497 [ #  # ][ #  # ]:          0 :                     aPropSet[PKG_MNFST_DIGEST].Value <<= rInfo.pStream->getDigest();
         [ #  # ][ #  # ]
     498         [ #  # ]:          0 :                     aPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
     499 [ #  # ][ #  # ]:          0 :                     aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
     500         [ #  # ]:          0 :                     aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
     501 [ #  # ][ #  # ]:          0 :                     aPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID;
     502         [ #  # ]:          0 :                     aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
     503 [ #  # ][ #  # ]:          0 :                     aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
     504         [ #  # ]:          0 :                     aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
     505 [ #  # ][ #  # ]:       1338 :                     aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
     506                 :            :                 }
     507         [ +  - ]:       1338 :             }
     508                 :            :         }
     509                 :            : 
     510                 :            :         // If the entry is already stored in the zip file in the format we
     511                 :            :         // want for this write...copy it raw
     512 [ +  - ][ +  - ]:       2676 :         if ( !bUseNonSeekableAccess
           [ +  -  +  + ]
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ +  + ]
     513                 :            :           && ( bRawStream || bTransportOwnEncrStreamAsRaw
     514                 :       1338 :             || ( rInfo.pStream->IsPackageMember() && !bToBeEncrypted
     515                 :            :               && ( ( rInfo.pStream->aEntry.nMethod == DEFLATED && bToBeCompressed )
     516                 :            :                 || ( rInfo.pStream->aEntry.nMethod == STORED && !bToBeCompressed ) ) ) ) )
     517                 :            :         {
     518                 :            :             // If it's a PackageMember, then it's an unbuffered stream and we need
     519                 :            :             // to get a new version of it as we can't seek backwards.
     520         [ +  - ]:        156 :             if ( rInfo.pStream->IsPackageMember() )
     521                 :            :             {
     522 [ +  - ][ +  - ]:        156 :                 xStream = rInfo.pStream->getRawData();
     523         [ -  + ]:        156 :                 if ( !xStream.is() )
     524                 :            :                 {
     525                 :            :                     // Make sure that we actually _got_ a new one !
     526                 :          0 :                     bSuccess = false;
     527                 :          0 :                     return bSuccess;
     528                 :            :                 }
     529                 :            :             }
     530                 :            : 
     531                 :            :             try
     532                 :            :             {
     533         [ -  + ]:        156 :                 if ( bRawStream )
     534 [ #  # ][ #  # ]:          0 :                     xStream->skipBytes( rInfo.pStream->GetMagicalHackPos() );
     535                 :            : 
     536         [ +  - ]:        156 :                 rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, sal_False );
     537                 :            :                 // the entry is provided to the ZipOutputStream that will delete it
     538                 :        156 :                 pAutoTempEntry.release();
     539                 :            : 
     540         [ +  - ]:        156 :                 uno::Sequence < sal_Int8 > aSeq ( n_ConstBufferSize );
     541                 :            :                 sal_Int32 nLength;
     542                 :            : 
     543         [ -  + ]:        156 :                 do
     544                 :            :                 {
     545 [ +  - ][ +  - ]:        156 :                     nLength = xStream->readBytes( aSeq, n_ConstBufferSize );
     546         [ +  - ]:        156 :                     rZipOut.rawWrite(aSeq, 0, nLength);
     547                 :            :                 }
     548                 :            :                 while ( nLength == n_ConstBufferSize );
     549                 :            : 
     550 [ +  - ][ +  - ]:        156 :                 rZipOut.rawCloseEntry();
              [ #  #  # ]
     551                 :            :             }
     552         [ #  # ]:          0 :             catch ( ZipException& )
     553                 :            :             {
     554                 :          0 :                 bSuccess = false;
     555                 :            :             }
     556         [ #  # ]:          0 :             catch ( IOException& )
     557                 :            :             {
     558                 :          0 :                 bSuccess = false;
     559                 :            :             }
     560                 :            :         }
     561                 :            :         else
     562                 :            :         {
     563                 :            :             // This stream is defenitly not a raw stream
     564                 :            : 
     565                 :            :             // If nonseekable access is used the stream should be at the beginning and
     566                 :            :             // is useless after the storing. Thus if the storing fails the package should
     567                 :            :             // be thrown away ( as actually it is done currently )!
     568                 :            :             // To allow to reuse the package after the error, the optimization must be removed!
     569                 :            : 
     570                 :            :             // If it's a PackageMember, then our previous reference held a 'raw' stream
     571                 :            :             // so we need to re-get it, unencrypted, uncompressed and positioned at the
     572                 :            :             // beginning of the stream
     573         [ -  + ]:       1182 :             if ( rInfo.pStream->IsPackageMember() )
     574                 :            :             {
     575 [ #  # ][ #  # ]:          0 :                 xStream = rInfo.pStream->getInputStream();
     576         [ #  # ]:          0 :                 if ( !xStream.is() )
     577                 :            :                 {
     578                 :            :                     // Make sure that we actually _got_ a new one !
     579                 :          0 :                     bSuccess = false;
     580                 :          0 :                     return bSuccess;
     581                 :            :                 }
     582                 :            :             }
     583                 :            : 
     584         [ +  + ]:       1182 :             if ( bToBeCompressed )
     585                 :            :             {
     586                 :       1106 :                 pTempEntry->nMethod = DEFLATED;
     587                 :       1106 :                 pTempEntry->nCrc = pTempEntry->nCompressedSize = pTempEntry->nSize = -1;
     588                 :            :             }
     589                 :            : 
     590                 :            :             try
     591                 :            :             {
     592         [ +  - ]:       1182 :                 rZipOut.putNextEntry ( *pTempEntry, rInfo.pStream, bToBeEncrypted);
     593                 :            :                 // the entry is provided to the ZipOutputStream that will delete it
     594                 :       1182 :                 pAutoTempEntry.release();
     595                 :            : 
     596                 :            :                 sal_Int32 nLength;
     597         [ +  - ]:       1182 :                 uno::Sequence < sal_Int8 > aSeq (n_ConstBufferSize);
     598         [ +  + ]:       1206 :                 do
     599                 :            :                 {
     600 [ +  - ][ +  - ]:       1206 :                     nLength = xStream->readBytes(aSeq, n_ConstBufferSize);
     601         [ +  - ]:       1206 :                     rZipOut.write(aSeq, 0, nLength);
     602                 :            :                 }
     603                 :            :                 while ( nLength == n_ConstBufferSize );
     604                 :            : 
     605 [ +  - ][ +  - ]:       1182 :                 rZipOut.closeEntry();
              [ #  #  # ]
     606                 :            :             }
     607         [ #  # ]:          0 :             catch ( ZipException& )
     608                 :            :             {
     609                 :          0 :                 bSuccess = false;
     610                 :            :             }
     611         [ #  # ]:          0 :             catch ( IOException& )
     612                 :            :             {
     613                 :          0 :                 bSuccess = false;
     614                 :            :             }
     615                 :            : 
     616         [ -  + ]:       1182 :             if ( bToBeEncrypted )
     617                 :            :             {
     618         [ #  # ]:          0 :                 ::rtl::Reference< EncryptionData > xEncData = rInfo.pStream->GetEncryptionData();
     619         [ #  # ]:          0 :                 if ( !xEncData.is() )
     620         [ #  # ]:          0 :                     throw uno::RuntimeException();
     621                 :            : 
     622         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_DIGEST].Name = sDigestProperty;
     623 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_DIGEST].Value <<= rInfo.pStream->getDigest();
         [ #  # ][ #  # ]
     624         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_ENCALG].Name = sEncryptionAlgProperty;
     625 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_ENCALG].Value <<= xEncData->m_nEncAlg;
     626         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_STARTALG].Name = sStartKeyAlgProperty;
     627 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_STARTALG].Value <<= xEncData->m_nStartKeyGenID;
     628         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_DIGESTALG].Name = sDigestAlgProperty;
     629 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_DIGESTALG].Value <<= xEncData->m_nCheckAlg;
     630         [ #  # ]:          0 :                 aPropSet[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
     631 [ #  # ][ #  # ]:          0 :                 aPropSet[PKG_MNFST_DERKEYSIZE].Value <<= xEncData->m_nDerivedKeySize;
     632                 :            : 
     633                 :          0 :                 rInfo.pStream->SetIsEncrypted ( sal_True );
     634                 :            :             }
     635                 :            :         }
     636                 :            : 
     637         [ +  - ]:       1338 :         if( bSuccess )
     638                 :            :         {
     639         [ +  + ]:       1338 :             if ( !rInfo.pStream->IsPackageMember() )
     640                 :            :             {
     641         [ +  - ]:       1182 :                 rInfo.pStream->CloseOwnStreamIfAny();
     642         [ +  - ]:       1182 :                 rInfo.pStream->SetPackageMember ( sal_True );
     643                 :            :             }
     644                 :            : 
     645         [ -  + ]:       1338 :             if ( bRawStream )
     646                 :            :             {
     647                 :            :                 // the raw stream was integrated and now behaves
     648                 :            :                 // as usual encrypted stream
     649         [ #  # ]:          0 :                 rInfo.pStream->SetToBeEncrypted( sal_True );
     650                 :            :             }
     651                 :            : 
     652                 :            :             // Then copy it back afterwards...
     653                 :       1338 :             ZipPackageFolder::copyZipEntry ( rInfo.pStream->aEntry, *pTempEntry );
     654                 :            : 
     655                 :            :             // Remove hacky bit from entry flags
     656         [ -  + ]:       1338 :             if ( rInfo.pStream->aEntry.nFlag & ( 1 << 4 ) )
     657                 :            :             {
     658                 :          0 :                 rInfo.pStream->aEntry.nFlag &= ~( 1 << 4 );
     659                 :          0 :                 rInfo.pStream->aEntry.nMethod = STORED;
     660                 :            :             }
     661                 :            : 
     662                 :            :             // TODO/LATER: get rid of this hack ( the encrypted stream size property is changed during saving )
     663         [ -  + ]:       1338 :             if ( rInfo.pStream->IsEncrypted() )
     664         [ #  # ]:          0 :                 rInfo.pStream->setSize( nOwnStreamOrigSize );
     665                 :            : 
     666                 :       1338 :             rInfo.pStream->aEntry.nOffset *= -1;
     667 [ -  + ][ +  - ]:       1338 :         }
     668                 :            :     }
     669                 :            : 
     670                 :            :     // folder can have a mediatype only in package format
     671 [ +  + ][ +  + ]:       2250 :     if ( aPropSet.getLength()
         [ +  + ][ +  - ]
                 [ +  + ]
     672                 :        459 :       && ( m_nFormat == embed::StorageFormats::PACKAGE || ( m_nFormat == embed::StorageFormats::OFOPXML && !rInfo.bFolder ) ) )
     673         [ +  - ]:       1254 :         rManList.push_back( aPropSet );
     674                 :            : 
     675         [ +  - ]:       2250 :     return bSuccess;
     676                 :            : }
     677                 :            : 
     678                 :       1374 : void ZipPackageFolder::saveContents( OUString &rPath, std::vector < uno::Sequence < PropertyValue > > &rManList, ZipOutputStream & rZipOut, const uno::Sequence < sal_Int8 >& rEncryptionKey, rtlRandomPool &rRandomPool )
     679                 :            :     throw( uno::RuntimeException )
     680                 :            : {
     681                 :       1374 :     bool bWritingFailed = false;
     682                 :            : 
     683 [ +  - ][ +  - ]:       1374 :     if ( maContents.begin() == maContents.end() && !rPath.isEmpty() && m_nFormat != embed::StorageFormats::OFOPXML )
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  +  
          #  #  #  #  #  
                   #  # ]
     684                 :            :     {
     685                 :            :         // it is an empty subfolder, use workaround to store it
     686         [ +  - ]:        330 :         ZipEntry* pTempEntry = new ZipEntry();
     687                 :        330 :         ZipPackageFolder::copyZipEntry ( *pTempEntry, aEntry );
     688         [ +  - ]:        330 :         pTempEntry->nPathLen = (sal_Int16)( OUStringToOString( rPath, RTL_TEXTENCODING_UTF8 ).getLength() );
     689                 :        330 :         pTempEntry->nExtraLen = -1;
     690                 :        330 :         pTempEntry->sPath = rPath;
     691                 :            : 
     692                 :            :         try
     693                 :            :         {
     694         [ +  - ]:        330 :             rZipOut.putNextEntry( *pTempEntry, NULL, sal_False );
     695         [ +  - ]:        330 :             rZipOut.rawCloseEntry();
     696                 :            :         }
     697         [ #  # ]:          0 :         catch ( ZipException& )
     698                 :            :         {
     699                 :          0 :             bWritingFailed = true;
     700                 :            :         }
     701         [ #  # ]:          0 :         catch ( IOException& )
     702                 :            :         {
     703                 :          0 :             bWritingFailed = true;
     704                 :            :         }
     705                 :            :     }
     706                 :            : 
     707                 :       1374 :     bool bMimeTypeStreamStored = false;
     708                 :       1374 :     OUString aMimeTypeStreamName("mimetype");
     709 [ +  + ][ +  + ]:       1374 :     if ( m_nFormat == embed::StorageFormats::ZIP && rPath.isEmpty() )
                 [ +  + ]
     710                 :            :     {
     711                 :            :         // let the "mimtype" stream in root folder be stored as the first stream if it is zip format
     712         [ +  - ]:        124 :         ContentHash::iterator aIter = maContents.find ( aMimeTypeStreamName );
     713 [ +  - ][ -  + ]:        124 :         if ( aIter != maContents.end() && !(*aIter).second->bFolder )
         [ #  # ][ #  # ]
                 [ +  - ]
           [ -  +  #  # ]
     714                 :            :         {
     715                 :          0 :             bMimeTypeStreamStored = true;
     716 [ #  # ][ #  # ]:        124 :             bWritingFailed = !saveChild( (*aIter).first, *(*aIter).second, rPath, rManList, rZipOut, rEncryptionKey, rRandomPool );
                 [ #  # ]
     717                 :            :         }
     718                 :            :     }
     719                 :            : 
     720 [ +  - ][ +  - ]:       3624 :     for ( ContentHash::const_iterator aCI = maContents.begin(), aEnd = maContents.end();
                 [ +  + ]
     721                 :            :           aCI != aEnd;
     722                 :            :           ++aCI)
     723                 :            :     {
     724         [ +  - ]:       2250 :         const OUString &rShortName = (*aCI).first;
     725         [ +  - ]:       2250 :         const ContentInfo &rInfo = *(*aCI).second;
     726                 :            : 
     727 [ #  # ][ +  - ]:       2250 :         if ( !bMimeTypeStreamStored || !rShortName.equals( aMimeTypeStreamName ) )
                 [ -  + ]
     728         [ +  - ]:       2250 :             bWritingFailed = !saveChild( rShortName, rInfo, rPath, rManList, rZipOut, rEncryptionKey, rRandomPool );
     729                 :            :     }
     730                 :            : 
     731         [ -  + ]:       1374 :     if( bWritingFailed )
     732         [ #  # ]:       1374 :         throw uno::RuntimeException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     733                 :       1374 : }
     734                 :            : 
     735                 :      10014 : void ZipPackageFolder::releaseUpwardRef( void )
     736                 :            : {
     737                 :            :     // Now it is possible that a package folder is disconnected from the package before removing of the folder.
     738                 :            :     // Such a scenario is used in storage implementation. When a new version of a folder is provided the old
     739                 :            :     // one is retrieved, removed from the package but preserved for the error handling.
     740                 :            :     // In this scenario the referencing to the parent is not really useful, since it requires disposing.
     741                 :            : 
     742                 :            :     // Actually there is no need in having a reference to the parent, it even make things more complicated and
     743                 :            :     // requires disposing mechanics. Using of a simple pointer seems to be easier solution and also a safe enough.
     744                 :            : 
     745                 :      10014 :     clearParent();
     746                 :            : 
     747                 :            : #if 0
     748                 :            :     for ( ContentHash::const_iterator aCI = maContents.begin();
     749                 :            :           aCI!=maContents.end();
     750                 :            :           aCI++)
     751                 :            :     {
     752                 :            :         ContentInfo &rInfo = * (*aCI).second;
     753                 :            :         if ( rInfo.bFolder )// && ! rInfo.pFolder->HasReleased () )
     754                 :            :             rInfo.pFolder->releaseUpwardRef();
     755                 :            :         else //if ( !rInfo.bFolder && !rInfo.pStream->HasReleased() )
     756                 :            :             rInfo.pStream->clearParent();
     757                 :            :     }
     758                 :            :     clearParent();
     759                 :            : 
     760                 :            :     OSL_ENSURE ( m_refCount == 1, "Ref-count is not 1!" );
     761                 :            : #endif
     762                 :      10014 : }
     763                 :            : 
     764                 :       6264 : sal_Int64 SAL_CALL ZipPackageFolder::getSomething( const uno::Sequence< sal_Int8 >& aIdentifier )
     765                 :            :     throw(uno::RuntimeException)
     766                 :            : {
     767                 :       6264 :     sal_Int64 nMe = 0;
     768   [ +  -  +  - ]:      12528 :     if ( aIdentifier.getLength() == 16 &&
                 [ +  - ]
     769                 :       6264 :          0 == memcmp(static_getImplementationId().getConstArray(),  aIdentifier.getConstArray(), 16 ) )
     770                 :       6264 :         nMe = reinterpret_cast < sal_Int64 > ( this );
     771                 :       6264 :     return nMe;
     772                 :            : }
     773                 :       3518 : void SAL_CALL ZipPackageFolder::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
     774                 :            :         throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, uno::RuntimeException)
     775                 :            : {
     776         [ +  + ]:       3518 :     if ( aPropertyName == "MediaType" )
     777                 :            :     {
     778                 :            :         // TODO/LATER: activate when zip ucp is ready
     779                 :            :         // if ( m_nFormat != embed::StorageFormats::PACKAGE )
     780                 :            :         //  throw UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     781                 :            : 
     782                 :       1759 :         aValue >>= sMediaType;
     783                 :            :     }
     784         [ +  - ]:       1759 :     else if ( aPropertyName == "Version" )
     785                 :       1759 :         aValue >>= m_sVersion;
     786         [ #  # ]:          0 :     else if ( aPropertyName == "Size" )
     787                 :          0 :         aValue >>= aEntry.nSize;
     788                 :            :     else
     789         [ #  # ]:          0 :         throw UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     790                 :       3518 : }
     791                 :      49366 : uno::Any SAL_CALL ZipPackageFolder::getPropertyValue( const OUString& PropertyName )
     792                 :            :         throw(UnknownPropertyException, WrappedTargetException, uno::RuntimeException)
     793                 :            : {
     794         [ +  + ]:      49366 :     if ( PropertyName == "MediaType" )
     795                 :            :     {
     796                 :            :         // TODO/LATER: activate when zip ucp is ready
     797                 :            :         // if ( m_nFormat != embed::StorageFormats::PACKAGE )
     798                 :            :         //  throw UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     799                 :            : 
     800                 :      24681 :         return uno::makeAny ( sMediaType );
     801                 :            :     }
     802         [ +  - ]:      24685 :     else if ( PropertyName == "Version" )
     803                 :      24685 :         return uno::makeAny( m_sVersion );
     804         [ #  # ]:          0 :     else if ( PropertyName == "Size" )
     805                 :          0 :         return uno::makeAny ( aEntry.nSize );
     806                 :            :     else
     807         [ #  # ]:      49366 :         throw UnknownPropertyException(OSL_LOG_PREFIX, uno::Reference< uno::XInterface >() );
     808                 :            : }
     809                 :            : 
     810                 :      26519 : void ZipPackageFolder::doInsertByName ( ZipPackageEntry *pEntry, sal_Bool bSetParent )
     811                 :            :         throw(IllegalArgumentException, ElementExistException, WrappedTargetException, uno::RuntimeException)
     812                 :            : {
     813                 :            :     try
     814                 :            :     {
     815         [ +  + ]:      26519 :         if ( pEntry->IsFolder() )
     816 [ +  - ][ +  - ]:      10356 :             maContents[pEntry->getName()] = new ContentInfo ( static_cast < ZipPackageFolder *> ( pEntry ) );
         [ +  - ][ +  - ]
     817                 :            :         else
     818 [ +  - ][ +  - ]:      16163 :             maContents[pEntry->getName()] = new ContentInfo ( static_cast < ZipPackageStream *> ( pEntry ) );
         [ +  - ][ +  - ]
     819                 :            :     }
     820         [ #  # ]:          0 :     catch(const uno::Exception& rEx)
     821                 :            :     {
     822                 :            :         (void)rEx;
     823                 :          0 :         throw;
     824                 :            :     }
     825         [ +  + ]:      26519 :     if ( bSetParent )
     826         [ +  - ]:       4033 :         pEntry->setParent ( *this );
     827                 :      26519 : }
     828                 :          0 : OUString ZipPackageFolder::getImplementationName()
     829                 :            :     throw (uno::RuntimeException)
     830                 :            : {
     831                 :          0 :     return OUString("ZipPackageFolder");
     832                 :            : }
     833                 :            : 
     834                 :          0 : uno::Sequence< OUString > ZipPackageFolder::getSupportedServiceNames()
     835                 :            :     throw (uno::RuntimeException)
     836                 :            : {
     837                 :          0 :     uno::Sequence< OUString > aNames(1);
     838         [ #  # ]:          0 :     aNames[0] = "com.sun.star.packages.PackageFolder";
     839                 :          0 :     return aNames;
     840                 :            : }
     841                 :          0 : sal_Bool SAL_CALL ZipPackageFolder::supportsService( OUString const & rServiceName )
     842                 :            :     throw (uno::RuntimeException)
     843                 :            : {
     844         [ #  # ]:          0 :     return rServiceName == getSupportedServiceNames()[0];
     845                 :            : }
     846                 :            : 
     847                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10