Blame source/vdo/base/lz4.c

Packit Service 310c69
/*
Packit Service 310c69
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service 310c69
 *
Packit Service 310c69
 * This program is free software; you can redistribute it and/or
Packit Service 310c69
 * modify it under the terms of the GNU General Public License
Packit Service 310c69
 * as published by the Free Software Foundation; either version 2
Packit Service 310c69
 * of the License, or (at your option) any later version.
Packit Service 310c69
 * 
Packit Service 310c69
 * This program is distributed in the hope that it will be useful,
Packit Service 310c69
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 310c69
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 310c69
 * GNU General Public License for more details.
Packit Service 310c69
 * 
Packit Service 310c69
 * You should have received a copy of the GNU General Public License
Packit Service 310c69
 * along with this program; if not, write to the Free Software
Packit Service 310c69
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 310c69
 * 02110-1301, USA. 
Packit Service 310c69
 *
Packit Service 310c69
 * $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/lz4.c#2 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
// Get the memcpy fixup from common.h.
Packit Service 310c69
#include "common.h"
Packit Service 310c69
Packit Service 310c69
/*
Packit Service 310c69
   LZ4 - Fast LZ compression algorithm
Packit Service 310c69
   Copyright (C) 2011-2012, Yann Collet.
Packit Service 310c69
   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Packit Service 310c69
Packit Service 310c69
   Redistribution and use in source and binary forms, with or without
Packit Service 310c69
   modification, are permitted provided that the following conditions are
Packit Service 310c69
   met:
Packit Service 310c69
Packit Service 310c69
       * Redistributions of source code must retain the above copyright
Packit Service 310c69
   notice, this list of conditions and the following disclaimer.
Packit Service 310c69
       * Redistributions in binary form must reproduce the above
Packit Service 310c69
   copyright notice, this list of conditions and the following disclaimer
Packit Service 310c69
   in the documentation and/or other materials provided with the
Packit Service 310c69
   distribution.
Packit Service 310c69
Packit Service 310c69
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit Service 310c69
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit Service 310c69
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit Service 310c69
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit Service 310c69
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit Service 310c69
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit Service 310c69
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit Service 310c69
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit Service 310c69
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit Service 310c69
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit Service 310c69
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 310c69
Packit Service 310c69
   You can contact the author at :
Packit Service 310c69
   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
Packit Service 310c69
   - LZ4 source repository : http://code.google.com/p/lz4/
Packit Service 310c69
*/
Packit Service 310c69
/*
Packit Service 310c69
 * With authors permission dual licensed as BSD/GPL for linux kernel
Packit Service 310c69
 *
Packit Service 310c69
 * Origin: http://lz4.googlecode.com/svn/trunk
Packit Service 310c69
 * Revision: 88
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// Tuning parameters
Packit Service 310c69
//**************************************
Packit Service 310c69
// MEMORY_USAGE :
Packit Service 310c69
// Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
Packit Service 310c69
// Increasing memory usage improves compression ratio
Packit Service 310c69
// Reduced memory usage can improve speed, due to cache effect
Packit Service 310c69
// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
Packit Service 310c69
#define MEMORY_USAGE 14
Packit Service 310c69
Packit Service 310c69
// NOTCOMPRESSIBLE_DETECTIONLEVEL :
Packit Service 310c69
// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"
Packit Service 310c69
// This may decrease compression ratio dramatically, but will be faster on incompressible data
Packit Service 310c69
// Increasing this value will make the algorithm search more before declaring a segment "incompressible"
Packit Service 310c69
// This could improve compression a bit, but will be slower on incompressible data
Packit Service 310c69
// The default value (6) is recommended
Packit Service 310c69
#define NOTCOMPRESSIBLE_DETECTIONLEVEL 6
Packit Service 310c69
Packit Service 310c69
// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE :
Packit Service 310c69
// This will provide a small boost to performance for big endian cpu, but the resulting compressed stream will be incompatible with little-endian CPU.
Packit Service 310c69
// You can set this option to 1 in situations where data will remain within closed environment
Packit Service 310c69
// This option is useless on Little_Endian CPU (such as x86)
Packit Service 310c69
//#define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// CPU Feature Detection
Packit Service 310c69
//**************************************
Packit Service 310c69
// 32 or 64 bits ?
Packit Service 310c69
#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || defined(__LP64__) || defined(_LP64) )   // Detects 64 bits mode
Packit Service 310c69
#  define LZ4_ARCH64 1
Packit Service 310c69
#else
Packit Service 310c69
#  define LZ4_ARCH64 0
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
// Little Endian or Big Endian ?
Packit Service 310c69
// GCC normally defines these three macros (and PDP-endian which we ignore).
Packit Service 310c69
#if !defined(__ORDER_LITTLE_ENDIAN__) || !defined(__ORDER_BIG_ENDIAN__) \
Packit Service 310c69
  || !defined(__BYTE_ORDER__)
Packit Service 310c69
#error "GCC byte order macros not defined?"
Packit Service 310c69
#endif
Packit Service 310c69
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
Packit Service 310c69
#  define LZ4_BIG_ENDIAN 1
Packit Service 310c69
#elif __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
Packit Service 310c69
#  error "fix byte order check"
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
Packit Service 310c69
// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected
Packit Service 310c69
// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance
Packit Service 310c69
#if defined(__ARM_FEATURE_UNALIGNED)
Packit Service 310c69
#  define LZ4_FORCE_UNALIGNED_ACCESS 1
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
// Define this parameter if your target system or compiler does not support hardware bit count
Packit Service 310c69
#if defined(_MSC_VER) && defined(_WIN32_WCE)            // Visual Studio for Windows CE does not support Hardware bit count
Packit Service 310c69
#  define LZ4_FORCE_SW_BITCOUNT
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// Compiler Options
Packit Service 310c69
//**************************************
Packit Service 310c69
#if __STDC_VERSION__ >= 199901L   // C99
Packit Service 310c69
/* "restrict" is a known keyword */
Packit Service 310c69
#else
Packit Service 310c69
#  define restrict // Disable restrict
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
#define _GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
Packit Service 310c69
Packit Service 310c69
#ifdef _MSC_VER  // Visual Studio
Packit Service 310c69
#  include <intrin.h>   // For Visual 2005
Packit Service 310c69
#  if LZ4_ARCH64	// 64-bit
Packit Service 310c69
#    pragma intrinsic(_BitScanForward64) // For Visual 2005
Packit Service 310c69
#    pragma intrinsic(_BitScanReverse64) // For Visual 2005
Packit Service 310c69
#  else
Packit Service 310c69
#    pragma intrinsic(_BitScanForward)   // For Visual 2005
Packit Service 310c69
#    pragma intrinsic(_BitScanReverse)   // For Visual 2005
Packit Service 310c69
#  endif
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
#ifdef _MSC_VER
Packit Service 310c69
#  define lz4_bswap16(x) _byteswap_ushort(x)
Packit Service 310c69
#else
Packit Service 310c69
#  define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
#if (_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
Packit Service 310c69
#  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
Packit Service 310c69
#else
Packit Service 310c69
#  define expect(expr,value)    (expr)
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// Includes
Packit Service 310c69
//**************************************
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
#  include <linux/string.h>   // for memset
Packit Service 310c69
#else /* __KERNEL__ */
Packit Service 310c69
#  include <stdlib.h>   // for malloc
Packit Service 310c69
#  include <string.h>   // for memset
Packit Service 310c69
#endif /* __KERNEL__ */
Packit Service 310c69
#include "lz4.h"
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// Basic Types
Packit Service 310c69
//**************************************
Packit Service 310c69
#if defined(_MSC_VER)    // Visual Studio does not support 'stdint' natively
Packit Service 310c69
#  define BYTE	unsigned __int8
Packit Service 310c69
#  define U16		unsigned __int16
Packit Service 310c69
#  define U32		unsigned __int32
Packit Service 310c69
#  define S32		__int32
Packit Service 310c69
#  define U64		unsigned __int64
Packit Service 310c69
#else
Packit Service 310c69
#  ifdef __KERNEL__
Packit Service 310c69
#    include <linux/types.h>
Packit Service 310c69
#  else /* __KERNEL__ */
Packit Service 310c69
#    include <stdint.h>
Packit Service 310c69
#  endif /* __KERNEL__ */
Packit Service 310c69
#  define BYTE	uint8_t
Packit Service 310c69
#  define U16		uint16_t
Packit Service 310c69
#  define U32		uint32_t
Packit Service 310c69
#  define S32		int32_t
Packit Service 310c69
#  define U64		uint64_t
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
#ifndef LZ4_FORCE_UNALIGNED_ACCESS
Packit Service 310c69
#  pragma pack(push, 1)
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
typedef struct _U16_S { U16 v; } U16_S;
Packit Service 310c69
typedef struct _U32_S { U32 v; } U32_S;
Packit Service 310c69
typedef struct _U64_S { U64 v; } U64_S;
Packit Service 310c69
Packit Service 310c69
#ifndef LZ4_FORCE_UNALIGNED_ACCESS
Packit Service 310c69
#  pragma pack(pop)
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
#define A64(x) (((U64_S *)(x))->v)
Packit Service 310c69
#define A32(x) (((U32_S *)(x))->v)
Packit Service 310c69
#define A16(x) (((U16_S *)(x))->v)
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// Constants
Packit Service 310c69
//**************************************
Packit Service 310c69
#define MINMATCH 4
Packit Service 310c69
Packit Service 310c69
#define HASH_LOG (MEMORY_USAGE-2)
Packit Service 310c69
#define HASHTABLESIZE (1 << HASH_LOG)
Packit Service 310c69
#define HASH_MASK (HASHTABLESIZE - 1)
Packit Service 310c69
Packit Service 310c69
#define SKIPSTRENGTH (NOTCOMPRESSIBLE_DETECTIONLEVEL>2?NOTCOMPRESSIBLE_DETECTIONLEVEL:2)
Packit Service 310c69
#define STACKLIMIT 13
Packit Service 310c69
#define HEAPMODE (HASH_LOG>STACKLIMIT)  // Defines if memory is allocated into the stack (local variable), or into the heap (malloc()).
Packit Service 310c69
#define COPYLENGTH 8
Packit Service 310c69
#define LASTLITERALS 5
Packit Service 310c69
#define MFLIMIT (COPYLENGTH+MINMATCH)
Packit Service 310c69
#define MINLENGTH (MFLIMIT+1)
Packit Service 310c69
Packit Service 310c69
#define MAXD_LOG 16
Packit Service 310c69
#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
Packit Service 310c69
Packit Service 310c69
#define ML_BITS  4
Packit Service 310c69
#define ML_MASK  ((1U<
Packit Service 310c69
#define RUN_BITS (8-ML_BITS)
Packit Service 310c69
#define RUN_MASK ((1U<
Packit Service 310c69
Packit Service 310c69
/*
Packit Service 310c69
 * Disable on-stack context allocation for linux kernel
Packit Service 310c69
 */
Packit Service 310c69
#undef STACKLIMIT
Packit Service 310c69
#define STACKLIMIT 0
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// Architecture-specific macros
Packit Service 310c69
//**************************************
Packit Service 310c69
#if LZ4_ARCH64	// 64-bit
Packit Service 310c69
#  define STEPSIZE 8
Packit Service 310c69
#  define UARCH U64
Packit Service 310c69
#  define AARCH A64
Packit Service 310c69
#  define LZ4_COPYSTEP(s,d)       A64(d) = A64(s); d+=8; s+=8;
Packit Service 310c69
#  define LZ4_COPYPACKET(s,d)     LZ4_COPYSTEP(s,d)
Packit Service 310c69
#  define LZ4_SECURECOPY(s,d,e)   if (d
Packit Service 310c69
#  define HTYPE                   U32
Packit Service 310c69
#  define INITBASE(base)          const BYTE* const base = ip
Packit Service 310c69
#else		// 32-bit
Packit Service 310c69
#  define STEPSIZE 4
Packit Service 310c69
#  define UARCH U32
Packit Service 310c69
#  define AARCH A32
Packit Service 310c69
#  define LZ4_COPYSTEP(s,d)       A32(d) = A32(s); d+=4; s+=4;
Packit Service 310c69
#  define LZ4_COPYPACKET(s,d)     LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
Packit Service 310c69
#  define LZ4_SECURECOPY          LZ4_WILDCOPY
Packit Service 310c69
#  define HTYPE                   const BYTE*
Packit Service 310c69
#  define INITBASE(base)          const int base = 0
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
#if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
Packit Service 310c69
#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
Packit Service 310c69
#  define LZ4_WRITE_LITTLEENDIAN_16(p,i)  { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p+=2; }
Packit Service 310c69
#else		// Little Endian
Packit Service 310c69
#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
Packit Service 310c69
#  define LZ4_WRITE_LITTLEENDIAN_16(p,v)  { A16(p) = v; p+=2; }
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// Local structures
Packit Service 310c69
//**************************************
Packit Service 310c69
struct refTables
Packit Service 310c69
{
Packit Service 310c69
    HTYPE hashTable[HASHTABLESIZE];
Packit Service 310c69
};
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//**************************************
Packit Service 310c69
// Macros
Packit Service 310c69
//**************************************
Packit Service 310c69
#define LZ4_HASH_FUNCTION(i)	(((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
Packit Service 310c69
#define LZ4_HASH_VALUE(p)		LZ4_HASH_FUNCTION(A32(p))
Packit Service 310c69
#define LZ4_WILDCOPY(s,d,e)		do { LZ4_COPYPACKET(s,d) } while (d
Packit Service 310c69
#define LZ4_BLINDCOPY(s,d,l)	{ BYTE* e=(d)+l; LZ4_WILDCOPY(s,d,e); d=e; }
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//****************************
Packit Service 310c69
// Private functions
Packit Service 310c69
//****************************
Packit Service 310c69
#if LZ4_ARCH64
Packit Service 310c69
Packit Service 310c69
static inline int LZ4_NbCommonBytes (register U64 val)
Packit Service 310c69
{
Packit Service 310c69
#if defined(LZ4_BIG_ENDIAN)
Packit Service 310c69
    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
Packit Service 310c69
    unsigned long r = 0;
Packit Service 310c69
    _BitScanReverse64( &r, val );
Packit Service 310c69
    return (int)(r>>3);
Packit Service 310c69
    #elif defined(__GNUC__) && (_GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
Packit Service 310c69
    return (__builtin_clzll(val) >> 3);
Packit Service 310c69
    #else
Packit Service 310c69
    int r;
Packit Service 310c69
    if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
Packit Service 310c69
    if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
Packit Service 310c69
    r += (!val);
Packit Service 310c69
    return r;
Packit Service 310c69
    #endif
Packit Service 310c69
#else
Packit Service 310c69
    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
Packit Service 310c69
    unsigned long r = 0;
Packit Service 310c69
    _BitScanForward64( &r, val );
Packit Service 310c69
    return (int)(r>>3);
Packit Service 310c69
    #elif defined(__GNUC__) && (_GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
Packit Service 310c69
    return (__builtin_ctzll(val) >> 3);
Packit Service 310c69
    #else
Packit Service 310c69
    static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
Packit Service 310c69
    return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];
Packit Service 310c69
    #endif
Packit Service 310c69
#endif
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
#else
Packit Service 310c69
Packit Service 310c69
static inline int LZ4_NbCommonBytes (register U32 val)
Packit Service 310c69
{
Packit Service 310c69
#if defined(LZ4_BIG_ENDIAN)
Packit Service 310c69
    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
Packit Service 310c69
    unsigned long r = 0;
Packit Service 310c69
    _BitScanReverse( &r, val );
Packit Service 310c69
    return (int)(r>>3);
Packit Service 310c69
    #elif defined(__GNUC__) && (_GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
Packit Service 310c69
    return (__builtin_clz(val) >> 3);
Packit Service 310c69
    #else
Packit Service 310c69
    int r;
Packit Service 310c69
    if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
Packit Service 310c69
    r += (!val);
Packit Service 310c69
    return r;
Packit Service 310c69
    #endif
Packit Service 310c69
#else
Packit Service 310c69
    #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
Packit Service 310c69
    unsigned long r = 0;
Packit Service 310c69
    _BitScanForward( &r, val );
Packit Service 310c69
    return (int)(r>>3);
Packit Service 310c69
    #elif defined(__GNUC__) && (_GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
Packit Service 310c69
    return (__builtin_ctz(val) >> 3);
Packit Service 310c69
    #else
Packit Service 310c69
    static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
Packit Service 310c69
    return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
Packit Service 310c69
    #endif
Packit Service 310c69
#endif
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//******************************
Packit Service 310c69
// Compression functions
Packit Service 310c69
//******************************
Packit Service 310c69
Packit Service 310c69
// LZ4_compressCtx :
Packit Service 310c69
// -----------------
Packit Service 310c69
// Compress 'isize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
Packit Service 310c69
// If it cannot achieve it, compression will stop, and result of the function will be zero.
Packit Service 310c69
// return : the number of bytes written in buffer 'dest', or 0 if the compression fails
Packit Service 310c69
Packit Service 310c69
static inline int LZ4_compressCtx(void** ctx,
Packit Service 310c69
                 const char* source,
Packit Service 310c69
                 char* dest,
Packit Service 310c69
                 int isize,
Packit Service 310c69
                 int maxOutputSize)
Packit Service 310c69
{
Packit Service 310c69
#if HEAPMODE
Packit Service 310c69
    struct refTables *srt = (struct refTables *) (*ctx);
Packit Service 310c69
    HTYPE* HashTable;
Packit Service 310c69
#else
Packit Service 310c69
    HTYPE HashTable[HASHTABLESIZE] = {0};
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
    const BYTE* ip = (BYTE*) source;
Packit Service 310c69
    INITBASE(base);
Packit Service 310c69
    const BYTE* anchor = ip;
Packit Service 310c69
    const BYTE* const iend = ip + isize;
Packit Service 310c69
    const BYTE* const mflimit = iend - MFLIMIT;
Packit Service 310c69
#define matchlimit (iend - LASTLITERALS)
Packit Service 310c69
Packit Service 310c69
    BYTE* op = (BYTE*) dest;
Packit Service 310c69
    BYTE* const oend = op + maxOutputSize;
Packit Service 310c69
Packit Service 310c69
    int len, length;
Packit Service 310c69
    const int skipStrength = SKIPSTRENGTH;
Packit Service 310c69
    U32 forwardH;
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
    // Init
Packit Service 310c69
    if (isize
Packit Service 310c69
#if HEAPMODE
Packit Service 310c69
    HashTable = (HTYPE*)(srt->hashTable);
Packit Service 310c69
    memset((void*)HashTable, 0, sizeof(srt->hashTable));
Packit Service 310c69
#else
Packit Service 310c69
    (void) ctx;
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
    // First Byte
Packit Service 310c69
    HashTable[LZ4_HASH_VALUE(ip)] = ip - base;
Packit Service 310c69
    ip++; forwardH = LZ4_HASH_VALUE(ip);
Packit Service 310c69
Packit Service 310c69
    // Main Loop
Packit Service 310c69
    for ( ; ; )
Packit Service 310c69
    {
Packit Service 310c69
        int findMatchAttempts = (1U << skipStrength) + 3;
Packit Service 310c69
        const BYTE* forwardIp = ip;
Packit Service 310c69
        const BYTE* ref;
Packit Service 310c69
        BYTE* token;
Packit Service 310c69
Packit Service 310c69
        // Find a match
Packit Service 310c69
        do {
Packit Service 310c69
            U32 h = forwardH;
Packit Service 310c69
            int step = findMatchAttempts++ >> skipStrength;
Packit Service 310c69
            ip = forwardIp;
Packit Service 310c69
            forwardIp = ip + step;
Packit Service 310c69
Packit Service 310c69
            if (unlikely(forwardIp > mflimit)) { goto _last_literals; }
Packit Service 310c69
Packit Service 310c69
            forwardH = LZ4_HASH_VALUE(forwardIp);
Packit Service 310c69
            ref = base + HashTable[h];
Packit Service 310c69
            HashTable[h] = ip - base;
Packit Service 310c69
Packit Service 310c69
        } while ((ref < ip - MAX_DISTANCE) || (A32(ref) != A32(ip)));
Packit Service 310c69
Packit Service 310c69
        // Catch up
Packit Service 310c69
        while ((ip>anchor) && (ref>(BYTE*)source) && unlikely(ip[-1]==ref[-1])) { ip--; ref--; }
Packit Service 310c69
Packit Service 310c69
        // Encode Literal length
Packit Service 310c69
        length = (int)(ip - anchor);
Packit Service 310c69
        token = op++;
Packit Service 310c69
        if (unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend)) return 0; 		// Check output limit
Packit Service 310c69
#ifdef _MSC_VER
Packit Service 310c69
        if (length>=(int)RUN_MASK)
Packit Service 310c69
        {
Packit Service 310c69
            int len = length-RUN_MASK;
Packit Service 310c69
            *token=(RUN_MASK<
Packit Service 310c69
            if (len>254)
Packit Service 310c69
            {
Packit Service 310c69
                do { *op++ = 255; len -= 255; } while (len>254);
Packit Service 310c69
                *op++ = (BYTE)len;
Packit Service 310c69
                memcpy(op, anchor, length);
Packit Service 310c69
                op += length;
Packit Service 310c69
                goto _next_match;
Packit Service 310c69
            }
Packit Service 310c69
            else
Packit Service 310c69
            *op++ = (BYTE)len;
Packit Service 310c69
        }
Packit Service 310c69
        else *token = (length<
Packit Service 310c69
#else
Packit Service 310c69
        if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
Packit Service 310c69
        else *token = (length<
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
        // Copy Literals
Packit Service 310c69
        LZ4_BLINDCOPY(anchor, op, length);
Packit Service 310c69
Packit Service 310c69
_next_match:
Packit Service 310c69
        // Encode Offset
Packit Service 310c69
        LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));
Packit Service 310c69
Packit Service 310c69
        // Start Counting
Packit Service 310c69
        ip+=MINMATCH; ref+=MINMATCH;   // MinMatch verified
Packit Service 310c69
        anchor = ip;
Packit Service 310c69
        while (likely(ip
Packit Service 310c69
        {
Packit Service 310c69
            UARCH diff = AARCH(ref) ^ AARCH(ip);
Packit Service 310c69
            if (!diff) { ip+=STEPSIZE; ref+=STEPSIZE; continue; }
Packit Service 310c69
            ip += LZ4_NbCommonBytes(diff);
Packit Service 310c69
            goto _endCount;
Packit Service 310c69
        }
Packit Service 310c69
        if (LZ4_ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { ip+=4; ref+=4; }
Packit Service 310c69
        if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }
Packit Service 310c69
        if ((ip
Packit Service 310c69
_endCount:
Packit Service 310c69
Packit Service 310c69
        // Encode MatchLength
Packit Service 310c69
        len = (int)(ip - anchor);
Packit Service 310c69
        if (unlikely(op + (1 + LASTLITERALS) + (len>>8) > oend)) return 0; 		// Check output limit
Packit Service 310c69
        if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
Packit Service 310c69
        else *token += len;
Packit Service 310c69
Packit Service 310c69
        // Test end of chunk
Packit Service 310c69
        if (ip > mflimit) { anchor = ip;  break; }
Packit Service 310c69
Packit Service 310c69
        // Fill table
Packit Service 310c69
        HashTable[LZ4_HASH_VALUE(ip-2)] = ip - 2 - base;
Packit Service 310c69
Packit Service 310c69
        // Test next position
Packit Service 310c69
        ref = base + HashTable[LZ4_HASH_VALUE(ip)];
Packit Service 310c69
        HashTable[LZ4_HASH_VALUE(ip)] = ip - base;
Packit Service 310c69
        if ((ref > ip - (MAX_DISTANCE + 1)) && (A32(ref) == A32(ip))) { token = op++; *token=0; goto _next_match; }
Packit Service 310c69
Packit Service 310c69
        // Prepare next loop
Packit Service 310c69
        anchor = ip++;
Packit Service 310c69
        forwardH = LZ4_HASH_VALUE(ip);
Packit Service 310c69
    }
Packit Service 310c69
Packit Service 310c69
_last_literals:
Packit Service 310c69
    // Encode Last Literals
Packit Service 310c69
    {
Packit Service 310c69
        int lastRun = (int)(iend - anchor);
Packit Service 310c69
        if (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize) return 0;
Packit Service 310c69
        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
Packit Service 310c69
        else *op++ = (lastRun<
Packit Service 310c69
        memcpy(op, anchor, iend - anchor);
Packit Service 310c69
        op += iend-anchor;
Packit Service 310c69
    }
Packit Service 310c69
Packit Service 310c69
    // End
Packit Service 310c69
    return (int) (((char*)op)-dest);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
// Note : this function is valid only if isize < LZ4_64KLIMIT
Packit Service 310c69
#define LZ4_64KLIMIT ((1<<16) + (MFLIMIT-1))
Packit Service 310c69
#define HASHLOG64K (HASH_LOG+1)
Packit Service 310c69
#define HASH64KTABLESIZE (1U<
Packit Service 310c69
#define LZ4_HASH64K_FUNCTION(i)	(((i) * 2654435761U) >> ((MINMATCH*8)-HASHLOG64K))
Packit Service 310c69
#define LZ4_HASH64K_VALUE(p)	LZ4_HASH64K_FUNCTION(A32(p))
Packit Service 310c69
static inline int LZ4_compress64kCtx(void** ctx,
Packit Service 310c69
                 const char* source,
Packit Service 310c69
                 char* dest,
Packit Service 310c69
                 int isize,
Packit Service 310c69
                 int maxOutputSize)
Packit Service 310c69
{
Packit Service 310c69
#if HEAPMODE
Packit Service 310c69
    struct refTables *srt = (struct refTables *) (*ctx);
Packit Service 310c69
    U16* HashTable;
Packit Service 310c69
#else
Packit Service 310c69
    U16 HashTable[HASH64KTABLESIZE] = {0};
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
    const BYTE* ip = (BYTE*) source;
Packit Service 310c69
    const BYTE* anchor = ip;
Packit Service 310c69
    const BYTE* const base = ip;
Packit Service 310c69
    const BYTE* const iend = ip + isize;
Packit Service 310c69
    const BYTE* const mflimit = iend - MFLIMIT;
Packit Service 310c69
#define matchlimit (iend - LASTLITERALS)
Packit Service 310c69
Packit Service 310c69
    BYTE* op = (BYTE*) dest;
Packit Service 310c69
    BYTE* const oend = op + maxOutputSize;
Packit Service 310c69
Packit Service 310c69
    int len, length;
Packit Service 310c69
    const int skipStrength = SKIPSTRENGTH;
Packit Service 310c69
    U32 forwardH;
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
    // Init
Packit Service 310c69
    if (isize
Packit Service 310c69
#if HEAPMODE
Packit Service 310c69
    HashTable = (U16*)(srt->hashTable);
Packit Service 310c69
    memset((void*)HashTable, 0, sizeof(srt->hashTable));
Packit Service 310c69
#else
Packit Service 310c69
    (void) ctx;
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
    // First Byte
Packit Service 310c69
    ip++; forwardH = LZ4_HASH64K_VALUE(ip);
Packit Service 310c69
Packit Service 310c69
    // Main Loop
Packit Service 310c69
    for ( ; ; )
Packit Service 310c69
    {
Packit Service 310c69
        int findMatchAttempts = (1U << skipStrength) + 3;
Packit Service 310c69
        const BYTE* forwardIp = ip;
Packit Service 310c69
        const BYTE* ref;
Packit Service 310c69
        BYTE* token;
Packit Service 310c69
Packit Service 310c69
        // Find a match
Packit Service 310c69
        do {
Packit Service 310c69
            U32 h = forwardH;
Packit Service 310c69
            int step = findMatchAttempts++ >> skipStrength;
Packit Service 310c69
            ip = forwardIp;
Packit Service 310c69
            forwardIp = ip + step;
Packit Service 310c69
Packit Service 310c69
            if (forwardIp > mflimit) { goto _last_literals; }
Packit Service 310c69
Packit Service 310c69
            forwardH = LZ4_HASH64K_VALUE(forwardIp);
Packit Service 310c69
            ref = base + HashTable[h];
Packit Service 310c69
            HashTable[h] = (U16)(ip - base);
Packit Service 310c69
Packit Service 310c69
        } while (A32(ref) != A32(ip));
Packit Service 310c69
Packit Service 310c69
        // Catch up
Packit Service 310c69
        while ((ip>anchor) && (ref>(BYTE*)source) && (ip[-1]==ref[-1])) { ip--; ref--; }
Packit Service 310c69
Packit Service 310c69
        // Encode Literal length
Packit Service 310c69
        length = (int)(ip - anchor);
Packit Service 310c69
        token = op++;
Packit Service 310c69
        if (unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend)) return 0; 		// Check output limit
Packit Service 310c69
#ifdef _MSC_VER
Packit Service 310c69
        if (length>=(int)RUN_MASK)
Packit Service 310c69
        {
Packit Service 310c69
            int len = length-RUN_MASK;
Packit Service 310c69
            *token=(RUN_MASK<
Packit Service 310c69
            if (len>254)
Packit Service 310c69
            {
Packit Service 310c69
                do { *op++ = 255; len -= 255; } while (len>254);
Packit Service 310c69
                *op++ = (BYTE)len;
Packit Service 310c69
                memcpy(op, anchor, length);
Packit Service 310c69
                op += length;
Packit Service 310c69
                goto _next_match;
Packit Service 310c69
            }
Packit Service 310c69
            else
Packit Service 310c69
            *op++ = (BYTE)len;
Packit Service 310c69
        }
Packit Service 310c69
        else *token = (length<
Packit Service 310c69
#else
Packit Service 310c69
        if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
Packit Service 310c69
        else *token = (length<
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
        // Copy Literals
Packit Service 310c69
        LZ4_BLINDCOPY(anchor, op, length);
Packit Service 310c69
Packit Service 310c69
_next_match:
Packit Service 310c69
        // Encode Offset
Packit Service 310c69
        LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));
Packit Service 310c69
Packit Service 310c69
        // Start Counting
Packit Service 310c69
        ip+=MINMATCH; ref+=MINMATCH;   // MinMatch verified
Packit Service 310c69
        anchor = ip;
Packit Service 310c69
        while (ip
Packit Service 310c69
        {
Packit Service 310c69
            UARCH diff = AARCH(ref) ^ AARCH(ip);
Packit Service 310c69
            if (!diff) { ip+=STEPSIZE; ref+=STEPSIZE; continue; }
Packit Service 310c69
            ip += LZ4_NbCommonBytes(diff);
Packit Service 310c69
            goto _endCount;
Packit Service 310c69
        }
Packit Service 310c69
        if (LZ4_ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { ip+=4; ref+=4; }
Packit Service 310c69
        if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }
Packit Service 310c69
        if ((ip
Packit Service 310c69
_endCount:
Packit Service 310c69
Packit Service 310c69
        // Encode MatchLength
Packit Service 310c69
        len = (int)(ip - anchor);
Packit Service 310c69
        if (unlikely(op + (1 + LASTLITERALS) + (len>>8) > oend)) return 0; 		// Check output limit
Packit Service 310c69
        if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
Packit Service 310c69
        else *token += len;
Packit Service 310c69
Packit Service 310c69
        // Test end of chunk
Packit Service 310c69
        if (ip > mflimit) { anchor = ip;  break; }
Packit Service 310c69
Packit Service 310c69
        // Fill table
Packit Service 310c69
        HashTable[LZ4_HASH64K_VALUE(ip-2)] = (U16)(ip - 2 - base);
Packit Service 310c69
Packit Service 310c69
        // Test next position
Packit Service 310c69
        ref = base + HashTable[LZ4_HASH64K_VALUE(ip)];
Packit Service 310c69
        HashTable[LZ4_HASH64K_VALUE(ip)] = (U16)(ip - base);
Packit Service 310c69
        if (A32(ref) == A32(ip)) { token = op++; *token=0; goto _next_match; }
Packit Service 310c69
Packit Service 310c69
        // Prepare next loop
Packit Service 310c69
        anchor = ip++;
Packit Service 310c69
        forwardH = LZ4_HASH64K_VALUE(ip);
Packit Service 310c69
    }
Packit Service 310c69
Packit Service 310c69
_last_literals:
Packit Service 310c69
    // Encode Last Literals
Packit Service 310c69
    {
Packit Service 310c69
        int lastRun = (int)(iend - anchor);
Packit Service 310c69
        if (op + lastRun + 1 + (lastRun-RUN_MASK+255)/255 > oend) return 0;
Packit Service 310c69
        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
Packit Service 310c69
        else *op++ = (lastRun<
Packit Service 310c69
        memcpy(op, anchor, iend - anchor);
Packit Service 310c69
        op += iend-anchor;
Packit Service 310c69
    }
Packit Service 310c69
Packit Service 310c69
    // End
Packit Service 310c69
    return (int) (((char*)op)-dest);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
int LZ4_compress_ctx_limitedOutput(void       *ctx,
Packit Service 310c69
                                   const char *source,
Packit Service 310c69
                                   char       *dest,
Packit Service 310c69
                                   int         isize,
Packit Service 310c69
                                   int         maxOutputSize)
Packit Service 310c69
{
Packit Service 310c69
  if (isize < LZ4_64KLIMIT) {
Packit Service 310c69
    return LZ4_compress64kCtx(&ctx, source, dest, isize, maxOutputSize);
Packit Service 310c69
  } else {
Packit Service 310c69
    return LZ4_compressCtx(&ctx, source, dest, isize, maxOutputSize);
Packit Service 310c69
  }
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
//****************************
Packit Service 310c69
// Decompression functions
Packit Service 310c69
//****************************
Packit Service 310c69
Packit Service 310c69
// Note : The decoding functions LZ4_uncompress() and LZ4_uncompress_unknownOutputSize()
Packit Service 310c69
//		are safe against "buffer overflow" attack type.
Packit Service 310c69
//		They will never write nor read outside of the provided output buffers.
Packit Service 310c69
//      LZ4_uncompress_unknownOutputSize() also insures that it will never read outside of the input buffer.
Packit Service 310c69
//		A corrupted input will produce an error result, a negative int, indicating the position of the error within input stream.
Packit Service 310c69
Packit Service 310c69
#ifdef LZ4_EVERYTHING
Packit Service 310c69
int LZ4_uncompress(const char* source, char* dest, int osize)
Packit Service 310c69
{
Packit Service 310c69
    // Local Variables
Packit Service 310c69
    const BYTE* restrict ip = (const BYTE*) source;
Packit Service 310c69
    const BYTE* ref;
Packit Service 310c69
Packit Service 310c69
    BYTE* op = (BYTE*) dest;
Packit Service 310c69
    BYTE* const oend = op + osize;
Packit Service 310c69
    BYTE* cpy;
Packit Service 310c69
Packit Service 310c69
    unsigned token;
Packit Service 310c69
Packit Service 310c69
    size_t length;
Packit Service 310c69
    size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
Packit Service 310c69
#if LZ4_ARCH64
Packit Service 310c69
    size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
    // Main Loop
Packit Service 310c69
    while (1)
Packit Service 310c69
    {
Packit Service 310c69
        // get runlength
Packit Service 310c69
        token = *ip++;
Packit Service 310c69
        if ((length=(token>>ML_BITS)) == RUN_MASK)  { size_t len; for (;(len=*ip++)==255;length+=255){} length += len; }
Packit Service 310c69
Packit Service 310c69
        // copy literals
Packit Service 310c69
        cpy = op+length;
Packit Service 310c69
        if (unlikely(cpy>oend-COPYLENGTH))
Packit Service 310c69
        {
Packit Service 310c69
            if (cpy != oend) goto _output_error;         // Error : not enough place for another match (min 4) + 5 literals
Packit Service 310c69
            memcpy(op, ip, length);
Packit Service 310c69
            ip += length;
Packit Service 310c69
            break;                                       // EOF
Packit Service 310c69
        }
Packit Service 310c69
        LZ4_WILDCOPY(ip, op, cpy); ip -= (op-cpy); op = cpy;
Packit Service 310c69
Packit Service 310c69
        // get offset
Packit Service 310c69
        LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;
Packit Service 310c69
        if (unlikely(ref < (BYTE* const)dest)) goto _output_error;   // Error : offset create reference outside destination buffer
Packit Service 310c69
Packit Service 310c69
        // get matchlength
Packit Service 310c69
        if ((length=(token&ML_MASK)) == ML_MASK) { for (;*ip==255;length+=255) {ip++;} length += *ip++; }
Packit Service 310c69
Packit Service 310c69
        // copy repeated sequence
Packit Service 310c69
        if (unlikely((op-ref)
Packit Service 310c69
        {
Packit Service 310c69
#if LZ4_ARCH64
Packit Service 310c69
            size_t dec64 = dec64table[op-ref];
Packit Service 310c69
#else
Packit Service 310c69
            const int dec64 = 0;
Packit Service 310c69
#endif
Packit Service 310c69
            op[0] = ref[0];
Packit Service 310c69
            op[1] = ref[1];
Packit Service 310c69
            op[2] = ref[2];
Packit Service 310c69
            op[3] = ref[3];
Packit Service 310c69
            op += 4, ref += 4; ref -= dec32table[op-ref];
Packit Service 310c69
            A32(op) = A32(ref);
Packit Service 310c69
            op += STEPSIZE-4; ref -= dec64;
Packit Service 310c69
        } else { LZ4_COPYSTEP(ref,op); }
Packit Service 310c69
        cpy = op + length - (STEPSIZE-4);
Packit Service 310c69
        if (cpy>oend-COPYLENGTH)
Packit Service 310c69
        {
Packit Service 310c69
            if (cpy > oend) goto _output_error;             // Error : request to write beyond destination buffer
Packit Service 310c69
            LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));
Packit Service 310c69
            while(op
Packit Service 310c69
            op=cpy;
Packit Service 310c69
            if (op == oend) goto _output_error;    // Check EOF (should never happen, since last 5 bytes are supposed to be literals)
Packit Service 310c69
            continue;
Packit Service 310c69
        }
Packit Service 310c69
        LZ4_SECURECOPY(ref, op, cpy);
Packit Service 310c69
        op=cpy;		// correction
Packit Service 310c69
    }
Packit Service 310c69
Packit Service 310c69
    // end of decoding
Packit Service 310c69
    return (int) (((char*)ip)-source);
Packit Service 310c69
Packit Service 310c69
    // write overflow error detected
Packit Service 310c69
_output_error:
Packit Service 310c69
    return (int) (-(((char*)ip)-source));
Packit Service 310c69
}
Packit Service 310c69
#endif /* LZ4_EVERYTHING */
Packit Service 310c69
Packit Service 310c69
int LZ4_uncompress_unknownOutputSize(
Packit Service 310c69
                const char* source,
Packit Service 310c69
                char* dest,
Packit Service 310c69
                int isize,
Packit Service 310c69
                int maxOutputSize)
Packit Service 310c69
{
Packit Service 310c69
    // Local Variables
Packit Service 310c69
    const BYTE* restrict ip = (const BYTE*) source;
Packit Service 310c69
    const BYTE* const iend = ip + isize;
Packit Service 310c69
    const BYTE* ref;
Packit Service 310c69
Packit Service 310c69
    BYTE* op = (BYTE*) dest;
Packit Service 310c69
    BYTE* const oend = op + maxOutputSize;
Packit Service 310c69
    BYTE* cpy;
Packit Service 310c69
Packit Service 310c69
    size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
Packit Service 310c69
#if LZ4_ARCH64
Packit Service 310c69
    size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
Packit Service 310c69
#endif
Packit Service 310c69
Packit Service 310c69
Packit Service 310c69
    // Main Loop
Packit Service 310c69
    while (ip
Packit Service 310c69
    {
Packit Service 310c69
        unsigned token;
Packit Service 310c69
        size_t length;
Packit Service 310c69
Packit Service 310c69
        // get runlength
Packit Service 310c69
        token = *ip++;
Packit Service 310c69
        if ((length=(token>>ML_BITS)) == RUN_MASK) { int s=255; while ((ip
Packit Service 310c69
Packit Service 310c69
        // copy literals
Packit Service 310c69
        cpy = op+length;
Packit Service 310c69
        if ((cpy>oend-COPYLENGTH) || (ip+length>iend-COPYLENGTH))
Packit Service 310c69
        {
Packit Service 310c69
            if (cpy > oend) goto _output_error;          // Error : writes beyond output buffer
Packit Service 310c69
            if (ip+length != iend) goto _output_error;   // Error : LZ4 format requires to consume all input at this stage
Packit Service 310c69
            memcpy(op, ip, length);
Packit Service 310c69
            op += length;
Packit Service 310c69
            break;                                       // Necessarily EOF, due to parsing restrictions
Packit Service 310c69
        }
Packit Service 310c69
        LZ4_WILDCOPY(ip, op, cpy); ip -= (op-cpy); op = cpy;
Packit Service 310c69
Packit Service 310c69
        // get offset
Packit Service 310c69
        LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;
Packit Service 310c69
        if (ref < (BYTE* const)dest) goto _output_error;   // Error : offset creates reference outside of destination buffer
Packit Service 310c69
Packit Service 310c69
        // get matchlength
Packit Service 310c69
        if ((length=(token&ML_MASK)) == ML_MASK) { while (ip
Packit Service 310c69
Packit Service 310c69
        // copy repeated sequence
Packit Service 310c69
        if (unlikely(op-ref
Packit Service 310c69
        {
Packit Service 310c69
#if LZ4_ARCH64
Packit Service 310c69
            size_t dec64 = dec64table[op-ref];
Packit Service 310c69
#else
Packit Service 310c69
            const int dec64 = 0;
Packit Service 310c69
#endif
Packit Service 310c69
            op[0] = ref[0];
Packit Service 310c69
            op[1] = ref[1];
Packit Service 310c69
            op[2] = ref[2];
Packit Service 310c69
            op[3] = ref[3];
Packit Service 310c69
            op += 4, ref += 4; ref -= dec32table[op-ref];
Packit Service 310c69
            A32(op) = A32(ref);
Packit Service 310c69
            op += STEPSIZE-4; ref -= dec64;
Packit Service 310c69
        } else { LZ4_COPYSTEP(ref,op); }
Packit Service 310c69
        cpy = op + length - (STEPSIZE-4);
Packit Service 310c69
        if (cpy>oend-COPYLENGTH)
Packit Service 310c69
        {
Packit Service 310c69
            if (cpy > oend) goto _output_error;    // Error : request to write outside of destination buffer
Packit Service 310c69
            LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));
Packit Service 310c69
            while(op
Packit Service 310c69
            op=cpy;
Packit Service 310c69
            if (op == oend) goto _output_error;    // Check EOF (should never happen, since last 5 bytes are supposed to be literals)
Packit Service 310c69
            continue;
Packit Service 310c69
        }
Packit Service 310c69
        LZ4_SECURECOPY(ref, op, cpy);
Packit Service 310c69
        op=cpy;		// correction
Packit Service 310c69
    }
Packit Service 310c69
Packit Service 310c69
    // end of decoding
Packit Service 310c69
    return (int) (((char*)op)-dest);
Packit Service 310c69
Packit Service 310c69
    // write overflow error detected
Packit Service 310c69
_output_error:
Packit Service 310c69
    return (int) (-(((char*)ip)-source));
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
int LZ4_context_size(void)
Packit Service 310c69
{
Packit Service 310c69
	return sizeof(struct refTables);
Packit Service 310c69
}