LCOV - code coverage report
Current view: top level - package/source/zipapi - ZipOutputStream.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 65 69 94.2 %
Date: 2014-11-03 Functions: 8 8 100.0 %
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 <ZipOutputStream.hxx>
      21             : 
      22             : #include <com/sun/star/packages/zip/ZipConstants.hpp>
      23             : #include <com/sun/star/io/XOutputStream.hpp>
      24             : #include <comphelper/storagehelper.hxx>
      25             : 
      26             : #include <PackageConstants.hxx>
      27             : #include <ZipEntry.hxx>
      28             : 
      29             : using namespace com::sun::star;
      30             : using namespace com::sun::star::io;
      31             : using namespace com::sun::star::uno;
      32             : using namespace com::sun::star::packages::zip::ZipConstants;
      33             : 
      34             : /** This class is used to write Zip files
      35             :  */
      36        1334 : ZipOutputStream::ZipOutputStream( const uno::Reference < io::XOutputStream > &xOStream )
      37             : : m_xStream(xOStream)
      38             : , m_aChucker(xOStream)
      39        1334 : , m_bFinished(false)
      40             : {
      41        1334 : }
      42             : 
      43        2668 : ZipOutputStream::~ZipOutputStream( void )
      44             : {
      45       20498 :     for (sal_Int32 i = 0, nEnd = m_aZipList.size(); i < nEnd; i++)
      46       19164 :         delete m_aZipList[i];
      47        1334 : }
      48             : 
      49       19164 : void ZipOutputStream::addEntry( ZipEntry *pZipEntry )
      50             : {
      51       19164 :     m_aZipList.push_back( pZipEntry );
      52       19164 : }
      53             : 
      54        1334 : void ZipOutputStream::finish(  )
      55             :     throw(IOException, RuntimeException)
      56             : {
      57        1334 :     if (m_bFinished)
      58        1334 :         return;
      59             : 
      60        1334 :     if (m_aZipList.size() < 1)
      61             :         OSL_FAIL("Zip file must have at least one entry!\n");
      62             : 
      63        1334 :     sal_Int32 nOffset= static_cast < sal_Int32 > (m_aChucker.GetPosition());
      64       20498 :     for (sal_Int32 i =0, nEnd = m_aZipList.size(); i < nEnd; i++)
      65       19164 :         writeCEN( *m_aZipList[i] );
      66        1334 :     writeEND( nOffset, static_cast < sal_Int32 > (m_aChucker.GetPosition()) - nOffset);
      67        1334 :     m_bFinished = true;
      68        1334 :     m_xStream->flush();
      69             : }
      70             : 
      71       19164 : ByteChucker& ZipOutputStream::getChucker()
      72             : {
      73       19164 :     return m_aChucker;
      74             : }
      75             : 
      76        1334 : void ZipOutputStream::writeEND(sal_uInt32 nOffset, sal_uInt32 nLength)
      77             :     throw(IOException, RuntimeException)
      78             : {
      79        1334 :     m_aChucker << ENDSIG;
      80        1334 :     m_aChucker << static_cast < sal_Int16 > ( 0 );
      81        1334 :     m_aChucker << static_cast < sal_Int16 > ( 0 );
      82        1334 :     m_aChucker << static_cast < sal_Int16 > ( m_aZipList.size() );
      83        1334 :     m_aChucker << static_cast < sal_Int16 > ( m_aZipList.size() );
      84        1334 :     m_aChucker << nLength;
      85        1334 :     m_aChucker << nOffset;
      86        1334 :     m_aChucker << static_cast < sal_Int16 > ( 0 );
      87        1334 : }
      88             : 
      89       57492 : static sal_uInt32 getTruncated( sal_Int64 nNum, bool *pIsTruncated )
      90             : {
      91       57492 :     if( nNum >= 0xffffffff )
      92             :     {
      93           0 :         *pIsTruncated = true;
      94           0 :         return 0xffffffff;
      95             :     }
      96             :     else
      97       57492 :         return static_cast< sal_uInt32 >( nNum );
      98             : }
      99             : 
     100       19164 : void ZipOutputStream::writeCEN( const ZipEntry &rEntry )
     101             :     throw(IOException, RuntimeException)
     102             : {
     103       19164 :     if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( rEntry.sPath, true ) )
     104           0 :         throw IOException("Unexpected character is used in file name." );
     105             : 
     106       19164 :     OString sUTF8Name = OUStringToOString( rEntry.sPath, RTL_TEXTENCODING_UTF8 );
     107       19164 :     sal_Int16 nNameLength       = static_cast < sal_Int16 > ( sUTF8Name.getLength() );
     108             : 
     109       19164 :     m_aChucker << CENSIG;
     110       19164 :     m_aChucker << rEntry.nVersion;
     111       19164 :     m_aChucker << rEntry.nVersion;
     112       19164 :     if (rEntry.nFlag & (1 << 4) )
     113             :     {
     114             :         // If it's an encrypted entry, we pretend its stored plain text
     115          10 :         ZipEntry *pEntry = const_cast < ZipEntry * > ( &rEntry );
     116          10 :         pEntry->nFlag &= ~(1 <<4 );
     117          10 :         m_aChucker << rEntry.nFlag;
     118          10 :         m_aChucker << static_cast < sal_Int16 > ( STORED );
     119             :     }
     120             :     else
     121             :     {
     122       19154 :         m_aChucker << rEntry.nFlag;
     123       19154 :         m_aChucker << rEntry.nMethod;
     124             :     }
     125       19164 :     bool bWrite64Header = false;
     126             : 
     127       19164 :     m_aChucker << static_cast < sal_uInt32> ( rEntry.nTime );
     128       19164 :     m_aChucker << static_cast < sal_uInt32> ( rEntry.nCrc );
     129       19164 :     m_aChucker << getTruncated( rEntry.nCompressedSize, &bWrite64Header );
     130       19164 :     m_aChucker << getTruncated( rEntry.nSize, &bWrite64Header );
     131       19164 :     m_aChucker << nNameLength;
     132       19164 :     m_aChucker << static_cast < sal_Int16> (0);
     133       19164 :     m_aChucker << static_cast < sal_Int16> (0);
     134       19164 :     m_aChucker << static_cast < sal_Int16> (0);
     135       19164 :     m_aChucker << static_cast < sal_Int16> (0);
     136       19164 :     m_aChucker << static_cast < sal_Int32> (0);
     137       19164 :     m_aChucker << getTruncated( rEntry.nOffset, &bWrite64Header );
     138             : 
     139       19164 :     if( bWrite64Header )
     140             :     {
     141             :         // FIXME64: need to append a ZIP64 header instead of throwing
     142             :         // We're about to silently lose people's data - which they are
     143             :         // unlikely to appreciate so fail instead:
     144           0 :         throw IOException( "File contains streams that are too large." );
     145             :     }
     146             : 
     147       38328 :     Sequence < sal_Int8 > aSequence( (sal_Int8*)sUTF8Name.getStr(), sUTF8Name.getLength() );
     148       38328 :     m_aChucker.WriteBytes( aSequence );
     149       19164 : }
     150             : 
     151             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10