LCOV - code coverage report
Current view: top level - hwpfilter/source - hgzip.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 78 125 62.4 %
Date: 2015-06-13 12:38:46 Functions: 7 7 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 "precompile.h"
      21             : 
      22             : #include <stdio.h>
      23             : #include <string.h>
      24             : #include <stdlib.h>
      25             : #include <errno.h>
      26             : #include "hgzip.h"
      27             : #include "hstream.hxx"
      28             : 
      29             : #ifndef local
      30             : #  define local static
      31             : #endif
      32             : 
      33             : #define Z_BUFSIZE   (1024 * 4)
      34             : 
      35             : #define ALLOC(size) malloc(size)
      36             : #define TRYFREE(p) {if (p) free(p);}
      37             : 
      38             : local int get_byte(gz_stream * s);
      39             : local int destroy(gz_stream * s);
      40             : local uLong getLong(gz_stream * s);
      41             : 
      42             : /* ===========================================================================
      43             :    Opens a gzip (.gz) file for reading or writing. The mode parameter
      44             :    is as in fopen ("rb" or "wb"). The file is given either by file descriptor
      45             :    or path name (if fd == -1).
      46             :      gz_open return NULL if the file could not be opened or if there was
      47             :    insufficient memory to allocate the (de)compression state; errno
      48             :    can be checked to distinguish the two cases (if errno is zero, the
      49             :    zlib error is Z_MEM_ERROR).
      50             : */
      51           1 : gz_stream *gz_open(HStream & _stream)
      52             : {
      53             :     int err;
      54             :     //int level = Z_DEFAULT_COMPRESSION;            /* compression level */
      55             : 
      56             : //  char        *p = (char*)mode;
      57             :     //char fmode[80];                               /* copy of mode, without the compression level */
      58             :     //char *m = fmode;
      59             :     gz_stream *s;
      60             : 
      61           1 :     s = static_cast<gz_stream *>(ALLOC(sizeof(gz_stream)));
      62           1 :     if (!s)
      63           0 :         return Z_NULL;
      64           1 :     s->stream.zalloc = nullptr;
      65           1 :     s->stream.zfree = nullptr;
      66           1 :     s->stream.opaque = nullptr;
      67           1 :     s->stream.next_in = s->inbuf = Z_NULL;
      68           1 :     s->stream.next_out = s->outbuf = Z_NULL;
      69           1 :     s->stream.avail_in = s->stream.avail_out = 0;
      70             : //s->_inputstream = NULL;
      71           1 :     s->z_err = Z_OK;
      72           1 :     s->z_eof = 0;
      73           1 :     s->crc = crc32(0L, Z_NULL, 0);
      74           1 :     s->msg = NULL;
      75           1 :     s->transparent = 0;
      76             : 
      77           1 :     s->mode = 'r';
      78             : 
      79             : //realking
      80           1 :     err = inflateInit2(&(s->stream), -MAX_WBITS);
      81           1 :     s->stream.next_in = s->inbuf = static_cast<Byte *>(ALLOC(Z_BUFSIZE));
      82             : 
      83           1 :     if (err != Z_OK || s->inbuf == Z_NULL)
      84             :     {
      85           0 :         destroy(s);
      86           0 :         return Z_NULL;
      87             :     }
      88             : 
      89           1 :     s->stream.avail_out = Z_BUFSIZE;
      90             : 
      91           1 :     errno = 0;
      92           1 :     s->_inputstream = &_stream;
      93             : 
      94           1 :     return s;
      95             : }
      96             : 
      97             : 
      98             : /* ===========================================================================
      99             :      Read a byte from a gz_stream; update next_in and avail_in. Return EOF
     100             :    for end of file.
     101             :    IN assertion: the stream s has been successfully opened for reading.
     102             : */
     103           8 : local int get_byte(gz_stream * s)
     104             : {
     105           8 :     if (s->z_eof)
     106           0 :         return EOF;
     107           8 :     if (s->stream.avail_in == 0)
     108             :     {
     109           0 :         errno = 0;
     110             : 
     111           0 :         s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
     112           0 :         if (s->stream.avail_in == 0)
     113             :         {
     114           0 :             s->z_eof = 1;
     115           0 :             return EOF;
     116             :         }
     117           0 :         s->stream.next_in = s->inbuf;
     118             :     }
     119           8 :     s->stream.avail_in--;
     120           8 :     return *(s->stream.next_in)++;
     121             : }
     122             : 
     123             : 
     124             : /* ===========================================================================
     125             :  * Cleanup then free the given gz_stream. Return a zlib error code.
     126             :  * Try freeing in the reverse order of allocations.
     127             :  */
     128           1 : local int destroy(gz_stream * s)
     129             : {
     130           1 :     int err = Z_OK;
     131             : 
     132           1 :     if (!s)
     133           0 :         return Z_STREAM_ERROR;
     134             : 
     135           1 :     TRYFREE(s->msg);
     136             : 
     137           1 :     if (s->stream.state != NULL)
     138             :     {
     139           1 :         err = inflateEnd(&(s->stream));
     140             :     }
     141           1 :     if (s->z_err < 0)
     142           0 :         err = s->z_err;
     143             : 
     144           1 :     TRYFREE(s->inbuf);
     145           1 :     TRYFREE(s->outbuf);
     146           1 :     TRYFREE(s);
     147           1 :     return err;
     148             : }
     149             : 
     150             : 
     151             : // typedef unsigned char  Byte
     152             : // typedef Byte  FAR Bytef;
     153             : /* ===========================================================================
     154             :    Reads the given number of uncompressed bytes from the compressed file.
     155             :    gz_read returns the number of bytes actually read (0 for end of file).
     156             : */
     157        3272 : int gz_read(gz_stream * file, voidp buf, unsigned len)
     158             : {
     159             : //printf("@@ gz_read : len : %d\t",len);
     160        3272 :     gz_stream *s = file;
     161        3272 :     Bytef *start = static_cast<Bytef *>(buf);                 /* starting point for crc computation */
     162             :     Byte *next_out;                               /* == stream.next_out but not forced far (for MSDOS) */
     163        3272 :     if (s == NULL)
     164           0 :         return Z_STREAM_ERROR;
     165             : 
     166        3272 :     if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
     167           0 :         return -1;
     168        3272 :     if (s->z_err == Z_STREAM_END)
     169           0 :         return 0;                                 /* EOF */
     170             : 
     171        3272 :     s->stream.next_out = next_out = static_cast<Bytef *>(buf);
     172        3272 :     s->stream.avail_out = len;
     173             : 
     174        9817 :     while (s->stream.avail_out != 0)
     175             :     {
     176        3274 :         if (s->transparent)
     177             :         {
     178             : /* Copy first the lookahead bytes: */
     179           0 :             uInt n = s->stream.avail_in;
     180             : 
     181           0 :             if (n > s->stream.avail_out)
     182           0 :                 n = s->stream.avail_out;
     183           0 :             if (n > 0)
     184             :             {
     185           0 :                 memcpy(s->stream.next_out, s->stream.next_in, n);
     186           0 :                 next_out += n;
     187           0 :                 s->stream.next_out = next_out;
     188           0 :                 s->stream.next_in += n;
     189           0 :                 s->stream.avail_out -= n;
     190           0 :                 s->stream.avail_in -= n;
     191             :             }
     192           0 :             if (s->stream.avail_out > 0)
     193             :             {
     194             :                 s->stream.avail_out -=
     195           0 :                     s->_inputstream->readBytes(next_out, s->stream.avail_out);
     196             :             }
     197           0 :             return (int) (len - s->stream.avail_out);
     198             :         }
     199        3274 :         if (s->stream.avail_in == 0 && !s->z_eof)
     200             :         {
     201             : 
     202           3 :             errno = 0;
     203           3 :             s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
     204           3 :             if (s->stream.avail_in == 0)
     205             :             {
     206           0 :                 s->z_eof = 1;
     207           0 :                 break;
     208             :             }
     209           3 :             s->stream.next_in = s->inbuf;
     210             :         }
     211        3274 :         s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
     212             : 
     213        3274 :         if (s->z_err == Z_STREAM_END)
     214             :         {
     215             : /* Check CRC and original size */
     216           1 :             s->crc = crc32(s->crc, start, (uInt) (s->stream.next_out - start));
     217           1 :             start = s->stream.next_out;
     218             : 
     219           1 :             if (getLong(s) != s->crc || getLong(s) != s->stream.total_out)
     220             :             {
     221           0 :                 s->z_err = Z_DATA_ERROR;
     222             :             }
     223           1 :             else if (s->z_err == Z_OK)
     224             :             {
     225           0 :                 inflateReset(&(s->stream));
     226           0 :                 s->crc = crc32(0L, Z_NULL, 0);
     227             :             }
     228             :         }
     229        3274 :         if (s->z_err != Z_OK || s->z_eof)
     230             :             break;
     231             :     }
     232        3272 :     s->crc = crc32(s->crc, start, (uInt) (s->stream.next_out - start));
     233        3272 :     return (int) (len - s->stream.avail_out);
     234             : }
     235             : 
     236             : /* ===========================================================================
     237             :      Flushes all pending output into the compressed file. The parameter
     238             :    flush is as in the deflate() function.
     239             :      gz_flush should be called only when strictly necessary because it can
     240             :    degrade compression.
     241             : */
     242           1 : int gz_flush(gz_stream * file, int flush)
     243             : {
     244             :     uInt len;
     245           1 :     bool done = false;
     246           1 :     gz_stream *s = file;
     247             : 
     248           1 :     if (s == NULL || s->mode != 'w')
     249           1 :         return Z_STREAM_ERROR;
     250             : 
     251           0 :     s->stream.avail_in = 0;                       /* should be zero already anyway */
     252             : 
     253             :     for (;;)
     254             :     {
     255           0 :         len = Z_BUFSIZE - s->stream.avail_out;
     256           0 :         if (len != 0)
     257             :         {
     258             : /*
     259             :       if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
     260             :     s->z_err = Z_ERRNO;
     261             :     return Z_ERRNO;
     262             :       }
     263             :       */
     264           0 :             s->stream.next_out = s->outbuf;
     265           0 :             s->stream.avail_out = Z_BUFSIZE;
     266             :         }
     267           0 :         if (done)
     268           0 :             break;
     269           0 :         s->z_err = deflate(&(s->stream), flush);
     270             : 
     271             : /* deflate has finished flushing only when it hasn't used up
     272             :  * all the available space in the output buffer:
     273             :  */
     274           0 :         done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
     275             : 
     276           0 :         if (s->z_err != Z_OK && s->z_err != Z_STREAM_END)
     277           0 :             break;
     278             :     }
     279           0 :     return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
     280             : }
     281             : 
     282             : 
     283             : /* ===========================================================================
     284             :    Reads a long in LSB order from the given gz_stream. Sets
     285             : */
     286           2 : local uLong getLong(gz_stream * s)
     287             : {
     288           2 :     uLong x = (unsigned char) get_byte(s);
     289             : 
     290           2 :     x += ((unsigned char) get_byte(s)) << 8;
     291           2 :     x += ((unsigned char) get_byte(s)) << 16;
     292           2 :     x += ((unsigned char) get_byte(s)) << 24;
     293           2 :     if (s->z_eof)
     294             :     {
     295           0 :         s->z_err = Z_DATA_ERROR;
     296             :     }
     297           2 :     return x;
     298             : }
     299             : 
     300             : 
     301             : /* ===========================================================================
     302             :    Flushes all pending output if necessary, closes the compressed file
     303             :    and deallocates all the (de)compression state.
     304             : */
     305           1 : int gz_close(gz_stream * file)
     306             : {
     307             : //  int err;
     308           1 :     gz_stream *s = file;
     309             : 
     310           1 :     if (s == NULL)
     311           0 :         return Z_STREAM_ERROR;
     312             : #if 0
     313             :     if (s->mode == 'w')
     314             :     {
     315             :         err = gz_flush(file, Z_FINISH);
     316             :         if (err != Z_OK)
     317             :             return destroy(s);
     318             :         putLong(s->file, s->crc);
     319             :         putLong(s->file, s->stream.total_in);
     320             :     }
     321             : #endif
     322           1 :     return destroy(s);
     323             : }
     324             : 
     325             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11