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

Generated by: LCOV version 1.10