LCOV - code coverage report
Current view: directory - redis/src - lzf_d.c (source / functions) Found Hit Coverage
Test: redis.info Lines: 39 27 69.2 %
Date: 2012-04-04 Functions: 1 1 100.0 %
Colors: not hit hit

       1                 : /*
       2                 :  * Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>
       3                 :  * 
       4                 :  * Redistribution and use in source and binary forms, with or without modifica-
       5                 :  * tion, are permitted provided that the following conditions are met:
       6                 :  * 
       7                 :  *   1.  Redistributions of source code must retain the above copyright notice,
       8                 :  *       this list of conditions and the following disclaimer.
       9                 :  * 
      10                 :  *   2.  Redistributions in binary form must reproduce the above copyright
      11                 :  *       notice, this list of conditions and the following disclaimer in the
      12                 :  *       documentation and/or other materials provided with the distribution.
      13                 :  * 
      14                 :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
      15                 :  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
      16                 :  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
      17                 :  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
      18                 :  * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      19                 :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
      20                 :  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      21                 :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
      22                 :  * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      23                 :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * the GNU General Public License ("GPL") version 2 or any later version,
      27                 :  * in which case the provisions of the GPL are applicable instead of
      28                 :  * the above. If you wish to allow the use of your version of this file
      29                 :  * only under the terms of the GPL and not to allow others to use your
      30                 :  * version of this file under the BSD license, indicate your decision
      31                 :  * by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL. If you do not delete the
      33                 :  * provisions above, a recipient may use your version of this file under
      34                 :  * either the BSD or the GPL.
      35                 :  */
      36                 : 
      37                 : #include "lzfP.h"
      38                 : 
      39                 : #if AVOID_ERRNO
      40                 : # define SET_ERRNO(n)
      41                 : #else
      42                 : # include <errno.h>
      43                 : # define SET_ERRNO(n) errno = (n)
      44                 : #endif
      45                 : 
      46                 : /*
      47                 : #if (__i386 || __amd64) && __GNUC__ >= 3
      48                 : # define lzf_movsb(dst, src, len)                \
      49                 :    asm ("rep movsb"                              \
      50                 :         : "=D" (dst), "=S" (src), "=c" (len)     \
      51                 :         :  "0" (dst),  "1" (src),  "2" (len));
      52                 : #endif
      53                 : */
      54                 : 
      55                 : unsigned int 
      56             582 : lzf_decompress (const void *const in_data,  unsigned int in_len,
      57                 :                 void             *out_data, unsigned int out_len)
      58                 : {
      59             582 :   u8 const *ip = (const u8 *)in_data;
      60             582 :   u8       *op = (u8 *)out_data;
      61             582 :   u8 const *const in_end  = ip + in_len;
      62             582 :   u8       *const out_end = op + out_len;
      63                 : 
      64                 :   do
      65                 :     {
      66           31370 :       unsigned int ctrl = *ip++;
      67                 : 
      68           31370 :       if (ctrl < (1 << 5)) /* literal run */
      69                 :         {
      70           10431 :           ctrl++;
      71                 : 
      72           10431 :           if (op + ctrl > out_end)
      73                 :             {
      74               0 :               SET_ERRNO (E2BIG);
      75               0 :               return 0;
      76                 :             }
      77                 : 
      78                 : #if CHECK_INPUT
      79           10431 :           if (ip + ctrl > in_end)
      80                 :             {
      81               0 :               SET_ERRNO (EINVAL);
      82               0 :               return 0;
      83                 :             }
      84                 : #endif
      85                 : 
      86                 : #ifdef lzf_movsb
      87                 :           lzf_movsb (op, ip, ctrl);
      88                 : #else
      89                 :           do
      90           40021 :             *op++ = *ip++;
      91           40021 :           while (--ctrl);
      92                 : #endif
      93                 :         }
      94                 :       else /* back reference */
      95                 :         {
      96           20939 :           unsigned int len = ctrl >> 5;
      97                 : 
      98           20939 :           u8 *ref = op - ((ctrl & 0x1f) << 8) - 1;
      99                 : 
     100                 : #if CHECK_INPUT
     101           20939 :           if (ip >= in_end)
     102                 :             {
     103               0 :               SET_ERRNO (EINVAL);
     104               0 :               return 0;
     105                 :             }
     106                 : #endif
     107           20939 :           if (len == 7)
     108                 :             {
     109              28 :               len += *ip++;
     110                 : #if CHECK_INPUT
     111              28 :               if (ip >= in_end)
     112                 :                 {
     113               0 :                   SET_ERRNO (EINVAL);
     114               0 :                   return 0;
     115                 :                 }
     116                 : #endif
     117                 :             }
     118                 : 
     119           20939 :           ref -= *ip++;
     120                 : 
     121           20939 :           if (op + len + 2 > out_end)
     122                 :             {
     123               0 :               SET_ERRNO (E2BIG);
     124               0 :               return 0;
     125                 :             }
     126                 : 
     127           20939 :           if (ref < (u8 *)out_data)
     128                 :             {
     129               0 :               SET_ERRNO (EINVAL);
     130               0 :               return 0;
     131                 :             }
     132                 : 
     133                 : #ifdef lzf_movsb
     134                 :           len += 2;
     135                 :           lzf_movsb (op, ref, len);
     136                 : #else
     137           20939 :           *op++ = *ref++;
     138           20939 :           *op++ = *ref++;
     139                 : 
     140                 :           do
     141           29430 :             *op++ = *ref++;
     142           29430 :           while (--len);
     143                 : #endif
     144                 :         }
     145                 :     }
     146           31370 :   while (ip < in_end);
     147                 : 
     148             582 :   return op - (u8 *)out_data;
     149                 : }
     150                 : 

Generated by: LCOV version 1.7