LCOV - code coverage report
Current view: top level - libreoffice/filter/source/placeware - zip.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 139 0.0 %
Date: 2012-12-27 Functions: 0 14 0.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 <osl/diagnose.h>
      21             : #include <rtl/crc.h>
      22             : 
      23             : #include "zip.hxx"
      24             : #include "zipfile.hxx"
      25             : 
      26             : using ::rtl::OString;
      27             : /** this struct describes one entry in a zip file */
      28           0 : struct ZipEntry
      29             : {
      30             :     OString name;           /* the name we used */
      31             :     sal_Int32 offset;       /* where the header starts */
      32             :     sal_Int32 endOffset;    /* where the file data ends */
      33             :     sal_Int32 crc;
      34             :     sal_Int32 modTime;      /* dos mod time & date */
      35             :     sal_Int32 fileLen;      /* file size, in bytes */
      36             : };
      37             : 
      38             : /** put one byte inside this stream */
      39           0 : static osl::File::RC putC( unsigned char c, osl::File& rFile )
      40             : {
      41             :     sal_uInt64 nBytesWritten;
      42           0 :     osl::File::RC nRC = rFile.write( &c, 1, nBytesWritten );
      43             : 
      44             :     OSL_ASSERT( nBytesWritten == 1 );
      45           0 :     return nRC;
      46             : }
      47             : 
      48             : /** write a short to the ZipFile */
      49           0 : void ZipFile::writeShort( sal_Int16 s)
      50             : {
      51           0 :     if( !isError() )
      52             :     {
      53           0 :         mnRC = putC( static_cast< unsigned char >( s & 0xff ), mrFile );
      54           0 :         if( !isError() )
      55           0 :             mnRC = putC( static_cast< unsigned char >( (s >> 8) & 0xff ), mrFile );
      56             :     }
      57           0 : }
      58             : 
      59             : /** write a long to the ZipFile */
      60             : 
      61           0 : void ZipFile::writeLong( sal_Int32 l )
      62             : {
      63           0 :     if( !isError() )
      64             :     {
      65           0 :         mnRC = putC( static_cast< unsigned char >( l & 0xff ), mrFile);
      66           0 :         if( !isError() )
      67             :         {
      68           0 :             mnRC = putC( static_cast< unsigned char >( (l >> 8) & 0xff ), mrFile);
      69           0 :             if( !isError() )
      70             :             {
      71           0 :                 mnRC = putC( static_cast< unsigned char >( (l >> 16) & 0xff ), mrFile);
      72           0 :                 if( !isError() )
      73             :                 {
      74           0 :                     mnRC = putC( static_cast< unsigned char >( (l >> 24) & 0xff ), mrFile);
      75             :                 }
      76             :             }
      77             :         }
      78             :     }
      79           0 : }
      80             : 
      81             : /** copy the zipentries file to the zipfile and updates the crc of that zipentry */
      82           0 : void ZipFile::copyAndCRC(ZipEntry *e, osl::File& rFile)
      83             : {
      84             :     char buf[2048];
      85             :     sal_uInt64 n, nWritten;
      86             : 
      87           0 :     e->crc = rtl_crc32( 0, 0L, 0 );
      88             : 
      89           0 :     while( !isError() )
      90             :     {
      91           0 :         mnRC = rFile.read( buf, sizeof(buf), n );
      92           0 :         if(n == 0)
      93           0 :             break;
      94             : 
      95           0 :         if( !isError() )
      96             :         {
      97           0 :             sal_uInt32 nTemp = static_cast<sal_uInt32>(n);
      98           0 :             e->crc = rtl_crc32( e->crc, (const void *) buf, nTemp );
      99           0 :             mnRC = mrFile.write( buf, n, nWritten );
     100             :             OSL_ASSERT( n == nWritten );
     101             :         }
     102             :     }
     103             : 
     104           0 :     if( !isError() )
     105             :     {
     106           0 :         sal_uInt64 nPosition = 0;
     107           0 :         mnRC = mrFile.getPos( nPosition );
     108           0 :         if( !isError() )
     109             :         {
     110           0 :             e->endOffset = static_cast< sal_Int32 >( nPosition );
     111             :         }
     112             :     }
     113           0 : }
     114             : 
     115             : /** write a yet empty local header for a zipentry to the zipfile */
     116           0 : void ZipFile::writeDummyLocalHeader(ZipEntry *e)
     117             : {
     118           0 :     sal_Int32 len = zf_lfhSIZE + e->name.getLength();
     119             :     sal_Int32 i;
     120             : 
     121           0 :     sal_uInt64 nPosition = 0;
     122           0 :     mnRC = mrFile.getPos( nPosition );
     123           0 :     if( !isError() )
     124             :     {
     125           0 :         e->offset = static_cast< sal_Int32 >( nPosition );
     126             : 
     127           0 :         for (i = 0; (i < len) && !isError(); ++i)
     128           0 :             mnRC = putC(0, mrFile);
     129             :     }
     130           0 : }
     131             : 
     132             : /** write the local header for a zipentry to the zipfile */
     133           0 : void ZipFile::writeLocalHeader(ZipEntry *e)
     134             : {
     135             :     TimeValue aTime;
     136           0 :     osl_getSystemTime( &aTime );
     137             : 
     138             :     oslDateTime aDate;
     139           0 :     osl_getDateTimeFromTimeValue( &aTime, &aDate );
     140             : 
     141             :     e->modTime = ((aDate.Year - 1980) << 25) | (aDate.Month << 21) |    (aDate.Day << 16) |
     142           0 :     (aDate.Hours << 11) | (aDate.Minutes << 5) | (aDate.Seconds >> 1);
     143             : 
     144           0 :     e->fileLen = e->endOffset - e->offset - zf_lfhSIZE - e->name.getLength();
     145             : 
     146           0 :     if(!isError())
     147             :     {
     148           0 :         mnRC = mrFile.setPos( osl_Pos_Absolut, e->offset );
     149             : 
     150           0 :         writeLong(zf_LFHSIGValue);                              // magic number
     151           0 :         writeShort(zf_Vers(1, 0));                              // extract version
     152           0 :         writeShort(0);                                          // flags
     153           0 :         writeShort(zf_compNone);                                // compression method
     154           0 :         writeLong(e->modTime);                                  // file mod date & time
     155           0 :         writeLong(e->crc);                                      // file crc
     156           0 :         writeLong(e->fileLen);                                  // compressed size
     157           0 :         writeLong(e->fileLen);                                  // uncompressed size
     158           0 :         writeShort((sal_Int16) e->name.getLength());                    // name length
     159           0 :         writeShort(0);                                          // extra length field
     160             : 
     161           0 :         if( !isError() )
     162             :         {
     163             :             sal_uInt64 nWritten;
     164           0 :             mnRC = mrFile.write( e->name.getStr(), e->name.getLength(), nWritten ); // file name
     165             :             OSL_ASSERT( nWritten == (sal_uInt64)e->name.getLength() );
     166           0 :             if( !isError() )
     167             :             {
     168           0 :                 mnRC = mrFile.setPos( osl_Pos_Absolut, e->endOffset );
     169             :             }
     170             :         }
     171             :     }
     172           0 : }
     173             : 
     174             : /* write a zipentry in the central dir to the zipfile */
     175           0 : void ZipFile::writeCentralDir(ZipEntry *e)
     176             : {
     177           0 :     writeLong(zf_CDHSIGValue);              // magic number
     178           0 :     writeShort(zf_Vers(1, 0));              // version made by
     179           0 :     writeShort(zf_Vers(1, 0));              // vers to extract
     180           0 :     writeShort(0);                          // flags
     181           0 :     writeShort(zf_compNone);                // compression method
     182           0 :     writeLong(e->modTime);                  // file mod time & date
     183           0 :     writeLong(e->crc);
     184           0 :     writeLong(e->fileLen);                  // compressed file size
     185           0 :     writeLong(e->fileLen);                  // uncompressed file size
     186           0 :     writeShort((sal_Int16) e->name.getLength());    // name length
     187           0 :     writeShort(0);                          // extra field length
     188           0 :     writeShort(0);                          // file comment length
     189           0 :     writeShort(0);                          // disk number start
     190           0 :     writeShort(0);                          // internal file attributes
     191           0 :     writeLong(0);                           // external file attributes
     192           0 :     writeLong(e->offset);                   // offset w.r.t disk
     193           0 :     if( !isError() )
     194             :     {
     195             :         sal_uInt64 nWritten;
     196           0 :         mrFile.write( e->name.getStr(), e->name.getLength(), nWritten );    // file name
     197             :         OSL_ASSERT( nWritten == (sal_uInt64)e->name.getLength() );
     198             :     }
     199           0 : }
     200             : 
     201             : /* write the end of the central dir to the zipfile */
     202           0 : void ZipFile::writeEndCentralDir(sal_Int32 nCdOffset, sal_Int32 nCdSize)
     203             : {
     204           0 :     writeLong(zf_ECDSIGValue);      // magic number
     205           0 :     writeShort(0);                  // disk num
     206           0 :     writeShort(0);                  // disk with central dir
     207           0 :     writeShort( static_cast< sal_Int16 >( maEntries.size() ) ); // number of file entries
     208           0 :     writeShort( static_cast< sal_Int16 >( maEntries.size() ) ); // number of file entries
     209           0 :     writeLong(nCdSize);             // central dir size
     210           0 :     writeLong(nCdOffset);
     211           0 :     writeShort(0);                  // comment len
     212           0 : }
     213             : 
     214             : 
     215             : /****************************************************************
     216             :  * The exported functions
     217             :  ****************************************************************/
     218             : 
     219             : /* Create a zip file for writing, return a handle for it.
     220             :  * RETURNS: A new zip-file output object, or NULL if it failed, in
     221             :  *   which case *errMsgBuffer will contain an error message string. */
     222           0 : ZipFile::ZipFile(osl::File& rFile )
     223           0 : : mrFile( rFile ), mbOpen( true ), mnRC( osl::File::E_None )
     224             : {
     225           0 : }
     226             : 
     227           0 : ZipFile::~ZipFile()
     228             : {
     229           0 :     if( mbOpen )
     230           0 :         close();
     231           0 : }
     232             : 
     233             : /* Add a file to this zip with the given name.
     234             :  * RETURNS: true if successful, else false. If false, the caller should
     235             :  *   call zip_Close() and delete the bum zip file.
     236             : */
     237           0 : bool ZipFile::addFile( osl::File& rFile, const OString& rName )
     238             : {
     239             :     OSL_ASSERT( mbOpen );
     240             : 
     241           0 :     if( !mbOpen )
     242           0 :         return false;
     243             : 
     244             :     OSL_ASSERT( !rName.isEmpty() );
     245             : 
     246           0 :     if(rName.isEmpty())
     247           0 :         return false;
     248             : 
     249           0 :     mnRC = rFile.open( osl_File_OpenFlag_Read );
     250             : 
     251           0 :     if( !isError() )
     252             :     {
     253           0 :         ZipEntry *e = new ZipEntry;
     254           0 :         e->name = rName;
     255           0 :         maEntries.push_back(e);
     256             : 
     257           0 :         writeDummyLocalHeader(e);
     258           0 :         if( !isError() )
     259             :         {
     260           0 :             copyAndCRC(e, rFile);
     261           0 :             if(!isError())
     262             :             {
     263           0 :                 writeLocalHeader(e);
     264             :             }
     265             :         }
     266             : 
     267           0 :         rFile.close();
     268             :     }
     269             : 
     270           0 :     return !isError();
     271             : }
     272             : 
     273             : /* Finish up the zip file, close it, and deallocate the zip file object.
     274             :  * RETURNS: true if successful, else false.
     275             : */
     276           0 : bool ZipFile::close()
     277             : {
     278             :     OSL_ASSERT( mbOpen );
     279             : 
     280           0 :     if( !mbOpen )
     281           0 :         return false;
     282             : 
     283           0 :     if( !isError() )
     284             :     {
     285             :         sal_uInt64 nCdOffset;
     286           0 :         mrFile.getPos( nCdOffset );
     287             : 
     288           0 :         std::vector< ZipEntry* >::iterator aIter( maEntries.begin() );
     289           0 :         while((aIter != maEntries.end()) && !isError())
     290             :         {
     291           0 :             writeCentralDir( (*aIter++) );
     292             :         }
     293             : 
     294           0 :         if( !isError() )
     295             :         {
     296             :             sal_uInt64 nCdSize;
     297           0 :             mrFile.getPos( nCdSize );
     298             : 
     299           0 :             nCdSize -= nCdOffset;
     300             : 
     301           0 :             if( !isError() )
     302             :             {
     303           0 :                 writeEndCentralDir(static_cast<sal_Int32>(nCdOffset), static_cast<sal_Int32>(nCdSize));
     304             :             }
     305             :         }
     306             :     }
     307             : 
     308           0 :     std::vector< ZipEntry* >::iterator aIter( maEntries.begin() );
     309           0 :     while( aIter != maEntries.end() )
     310             :     {
     311           0 :         delete (*aIter++);
     312             :     }
     313             : 
     314           0 :     mbOpen = false;
     315             : 
     316           0 :     return !isError();
     317             : }
     318             : 
     319             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10