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

Generated by: LCOV version 1.10