/*
* LZ4 - Fast LZ compression algorithm
* Copyright (C) 2011 - 2016, Yann Collet.
* BSD 2 - Clause License (http://www.opensource.org/licenses/bsd - license.php)
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* You can contact the author at :
* - LZ4 homepage : http://www.lz4.org
* - LZ4 source repository : https://github.com/lz4/lz4
*
* Changed for kernel usage by:
* Sven Schmidt <4sschmid@informatik.uni-hamburg.de>
*/
/*-************************************
* Dependencies
**************************************/
#include <linux/lz4.h>
#include "lz4defs.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/unaligned.h>
static const int LZ4_minLength = (MFLIMIT + 1);
static const int LZ4_64Klimit = ((64 * KB) + (MFLIMIT - 1));
/*-******************************
* Compression functions
********************************/
static FORCE_INLINE U32 LZ4_hash4(
U32 sequence,
tableType_t const tableType)
{
if (tableType == byU16)
return ((sequence * 2654435761U)
>> ((MINMATCH * 8) - (LZ4_HASHLOG + 1)));
else
return ((sequence * 2654435761U)
>> ((MINMATCH * 8) - LZ4_HASHLOG));
}
static FORCE_INLINE U32 LZ4_hash5(
U64 sequence,
tableType_t const tableType)
{
const U32 hashLog = (tableType == byU16)
? LZ4_HASHLOG + 1
: LZ4_HASHLOG;
#if LZ4_LITTLE_ENDIAN
static const U64 prime5bytes = 889523592379ULL;
return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog));
#else
static const U64 prime8bytes = 11400714785074694791ULL;
return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog));
#endif
}
static FORCE_INLINE U32 LZ4_hashPosition(
const void *p,
tableType_t const tableType)
{
#if LZ4_ARCH64
if (tableType == byU32)
return LZ4_hash5(LZ4_read_ARCH(p), tableType);
#endif
return LZ4_hash4(LZ4_read32(p), tableType);
}
static void LZ4_putPositionOnHash(
const BYTE *p,
U32 h,
void *tableBase,
tableType_t const tableType,
const BYTE *srcBase)
{
switch (tableType) {
case byPtr:
{
const BYTE **hashTable = (const BYTE **)tableBase;
hashTable[h] = p;
return;
}
case byU32:
{
U32 *hashTable = (U32 *) tableBase;
hashTable[h] = (U32)(p - srcBase);
return;
}
case byU16:
{
U16 *hashTable = (U16 *) tableBase;
hashTable[h] = (U16)(p - srcBase);
return;
}
}
}
static FORCE_INLINE void LZ4_putPosition(
const BYTE *p,
void *tableBase,
tableType_t tableType,
const BYTE *srcBase)
{
U32 const h = LZ4_hashPosition(p, tableType);
LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
}
static const BYTE *LZ4_getPositionOnHash(
U32 h,
void *tableBase,
tableType_t tableType,
const BYTE *srcBase)
{
if (tableType == byPtr) {
const BYTE **hashTable = (const BYTE **) tableBase;
return hashTable[h];
}
if (tableType == byU32) {
const U32 * const hashTable = (U32 *) tableBase;
return hashTable[h] + srcBase;
}
{
/* default, to ensure a return */
const U16 * const hashTable = (U16 *) tableBase;
return hashTable[h] + srcBase;
}
}
static FORCE_INLINE const BYTE *LZ4_getPosition(
const BYTE *p,
void *tableBase,
tableType_t tableType,
const BYTE *srcBase)
{
U32 const h = LZ4_hashPosition(p, tableType);
return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
}
/*
* LZ4_compress_generic() :
* inlined, to ensure branches are decided at compilation time
*/
static FORCE_INLINE int LZ4_compress_generic(
LZ4_stream_t_internal *<