LCOV - code coverage report
Current view: top level - hwpfilter/source - hgzip.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 79 125 63.2 %
Date: 2014-04-11 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.h"
      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 = (gz_stream *) ALLOC(sizeof(gz_stream));
      62           1 :     if (!s)
      63           0 :         return Z_NULL;
      64           1 :     s->stream.zalloc = (alloc_func) 0;
      65           1 :     s->stream.zfree = (free_func) 0;
      66           1 :     s->stream.opaque = (voidpf) 0;
      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 = (Byte *) ALLOC(Z_BUFSIZE);
      82             : 
      83           1 :     if (err != Z_OK || s->inbuf == Z_NULL)
      84             :     {
      85           0 :         return destroy(s), (gz_stream *) Z_NULL;
      86             :     }
      87             : 
      88           1 :     s->stream.avail_out = Z_BUFSIZE;
      89             : 
      90           1 :     errno = 0;
      91           1 :     s->_inputstream = &_stream;
      92             : 
      93           1 :     return (gz_stream *) s;
      94             : }
      95             : 
      96             : 
      97             : /* ===========================================================================
      98             :      Read a byte from a gz_stream; update next_in and avail_in. Return EOF
      99             :    for end of file.
     100             :    IN assertion: the stream s has been successfully opened for reading.
     101             : */
     102           8 : local int get_byte(gz_stream * s)
     103             : {
     104           8 :     if (s->z_eof)
     105           0 :         return EOF;
     106           8 :     if (s->stream.avail_in == 0)
     107             :     {
     108           0 :         errno = 0;
     109             : 
     110           0 :         s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
     111           0 :         if (s->stream.avail_in == 0)
     112             :         {
     113           0 :             s->z_eof = 1;
     114           0 :             return EOF;
     115             :         }
     116           0 :         s->stream.next_in = s->inbuf;
     117             :     }
     118           8 :     s->stream.avail_in--;
     119           8 :     return *(s->stream.next_in)++;
     120             : }
     121             : 
     122             : 
     123             : /* ===========================================================================
     124             :  * Cleanup then free the given gz_stream. Return a zlib error code.
     125             :  * Try freeing in the reverse order of allocations.
     126             :  */
     127           1 : local int destroy(gz_stream * s)
     128             : {
     129           1 :     int err = Z_OK;
     130             : 
     131           1 :     if (!s)
     132           0 :         return Z_STREAM_ERROR;
     133             : 
     134           1 :     TRYFREE(s->msg);
     135             : 
     136           1 :     if (s->stream.state != NULL)
     137             :     {
     138           1 :         err = inflateEnd(&(s->stream));
     139             :     }
     140           1 :     if (s->z_err < 0)
     141           0 :         err = s->z_err;
     142             : 
     143           1 :     TRYFREE(s->inbuf);
     144           1 :     TRYFREE(s->outbuf);
     145           1 :     TRYFREE(s);
     146           1 :     return err;
     147             : }
     148             : 
     149             : 
     150             : // typedef unsigned char  Byte
     151             : // typedef Byte  FAR Bytef;
     152             : /* ===========================================================================
     153             :    Reads the given number of uncompressed bytes from the compressed file.
     154             :    gz_read returns the number of bytes actually read (0 for end of file).
     155             : */
     156        3272 : int gz_read(gz_stream * file, voidp buf, unsigned len)
     157             : {
     158             : //printf("@@ gz_read : len : %d\t",len);
     159        3272 :     gz_stream *s = (gz_stream *) file;
     160        3272 :     Bytef *start = (Bytef *) buf;                 /* starting point for crc computation */
     161             :     Byte *next_out;                               /* == stream.next_out but not forced far (for MSDOS) */
     162        3272 :     if (s == NULL)
     163           0 :         return Z_STREAM_ERROR;
     164             : 
     165        3272 :     if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)
     166           0 :         return -1;
     167        3272 :     if (s->z_err == Z_STREAM_END)
     168           0 :         return 0;                                 /* EOF */
     169             : 
     170        3272 :     s->stream.next_out = next_out = (Bytef *) buf;
     171        3272 :     s->stream.avail_out = len;
     172             : 
     173        9817 :     while (s->stream.avail_out != 0)
     174             :     {
     175        3274 :         if (s->transparent)
     176             :         {
     177             : /* Copy first the lookahead bytes: */
     178           0 :             uInt n = s->stream.avail_in;
     179             : 
     180           0 :             if (n > s->stream.avail_out)
     181           0 :                 n = s->stream.avail_out;
     182           0 :             if (n > 0)
     183             :             {
     184           0 :                 memcpy(s->stream.next_out, s->stream.next_in, n);
     185           0 :                 next_out += n;
     186           0 :                 s->stream.next_out = next_out;
     187           0 :                 s->stream.next_in += n;
     188           0 :                 s->stream.avail_out -= n;
     189           0 :                 s->stream.avail_in -= n;
     190             :             }
     191           0 :             if (s->stream.avail_out > 0)
     192             :             {
     193             :                 s->stream.avail_out -=
     194           0 :                     s->_inputstream->readBytes(next_out, s->stream.avail_out);
     195             :             }
     196           0 :             return (int) (len - s->stream.avail_out);
     197             :         }
     198        3274 :         if (s->stream.avail_in == 0 && !s->z_eof)
     199             :         {
     200             : 
     201           3 :             errno = 0;
     202           3 :             s->stream.avail_in = s->_inputstream->readBytes(s->inbuf, Z_BUFSIZE);
     203           3 :             if (s->stream.avail_in == 0)
     204             :             {
     205           0 :                 s->z_eof = 1;
     206           0 :                 break;
     207             :             }
     208           3 :             s->stream.next_in = s->inbuf;
     209             :         }
     210        3274 :         s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
     211             : 
     212        3274 :         if (s->z_err == Z_STREAM_END)
     213             :         {
     214             : /* Check CRC and original size */
     215           1 :             s->crc = crc32(s->crc, start, (uInt) (s->stream.next_out - start));
     216           1 :             start = s->stream.next_out;
     217             : 
     218           1 :             if (getLong(s) != s->crc || getLong(s) != s->stream.total_out)
     219             :             {
     220           0 :                 s->z_err = Z_DATA_ERROR;
     221             :             }
     222           1 :             else if (s->z_err == Z_OK)
     223             :             {
     224           0 :                 inflateReset(&(s->stream));
     225           0 :                 s->crc = crc32(0L, Z_NULL, 0);
     226             :             }
     227             :         }
     228        3274 :         if (s->z_err != Z_OK || s->z_eof)
     229             :             break;
     230             :     }
     231        3272 :     s->crc = crc32(s->crc, start, (uInt) (s->stream.next_out - start));
     232        3272 :     return (int) (len - s->stream.avail_out);
     233             : }
     234             : 
     235             : /* ===========================================================================
     236             :      Flushes all pending output into the compressed file. The parameter
     237             :    flush is as in the deflate() function.
     238             :      gz_flush should be called only when strictly necessary because it can
     239             :    degrade compression.
     240             : */
     241           1 : int gz_flush(gz_stream * file, int flush)
     242             : {
     243             :     uInt len;
     244           1 :     bool done = false;
     245           1 :     gz_stream *s = (gz_stream *) file;
     246             : 
     247           1 :     if (s == NULL || s->mode != 'w')
     248           1 :         return Z_STREAM_ERROR;
     249             : 
     250           0 :     s->stream.avail_in = 0;                       /* should be zero already anyway */
     251             : 
     252             :     for (;;)
     253             :     {
     254           0 :         len = Z_BUFSIZE - s->stream.avail_out;
     255           0 :         if (len != 0)
     256             :         {
     257             : /*
     258             :       if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
     259             :     s->z_err = Z_ERRNO;
     260             :     return Z_ERRNO;
     261             :       }
     262             :       */
     263           0 :             s->stream.next_out = s->outbuf;
     264           0 :             s->stream.avail_out = Z_BUFSIZE;
     265             :         }
     266           0 :         if (done)
     267           0 :             break;
     268           0 :         s->z_err = deflate(&(s->stream), flush);
     269             : 
     270             : /* deflate has finished flushing only when it hasn't used up
     271             :  * all the available space in the output buffer:
     272             :  */
     273           0 :         done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
     274             : 
     275           0 :         if (s->z_err != Z_OK && s->z_err != Z_STREAM_END)
     276           0 :             break;
     277             :     }
     278           0 :     return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
     279             : }
     280             : 
     281             : 
     282             : /* ===========================================================================
     283             :    Reads a long in LSB order from the given gz_stream. Sets
     284             : */
     285           2 : local uLong getLong(gz_stream * s)
     286             : {
     287           2 :     uLong x = (uLong) get_byte(s);
     288             :     int c;
     289             : 
     290           2 :     x += ((uLong) get_byte(s)) << 8;
     291           2 :     x += ((uLong) get_byte(s)) << 16;
     292           2 :     c = get_byte(s);
     293           2 :     if (c == EOF)
     294           0 :         s->z_err = Z_DATA_ERROR;
     295           2 :     x += ((uLong) c) << 24;
     296           2 :     return x;
     297             : }
     298             : 
     299             : 
     300             : /* ===========================================================================
     301             :    Flushes all pending output if necessary, closes the compressed file
     302             :    and deallocates all the (de)compression state.
     303             : */
     304           1 : int gz_close(gz_stream * file)
     305             : {
     306             : //  int err;
     307           1 :     gz_stream *s = (gz_stream *) file;
     308             : 
     309           1 :     if (s == NULL)
     310           0 :         return Z_STREAM_ERROR;
     311             : #if 0
     312             :     if (s->mode == 'w')
     313             :     {
     314             :         err = gz_flush(file, Z_FINISH);
     315             :         if (err != Z_OK)
     316             :             return destroy(s);
     317             :         putLong(s->file, s->crc);
     318             :         putLong(s->file, s->stream.total_in);
     319             :     }
     320             : #endif
     321           1 :     return destroy(s);
     322             : }
     323             : 
     324             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10