sereal 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,111 @@
1
+ /*
2
+ LZ4 HC - High Compression Mode of LZ4
3
+ Header File
4
+ Copyright (C) 2011-2013, Yann Collet.
5
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are
9
+ met:
10
+
11
+ * Redistributions of source code must retain the above copyright
12
+ notice, this list of conditions and the following disclaimer.
13
+ * Redistributions in binary form must reproduce the above
14
+ copyright notice, this list of conditions and the following disclaimer
15
+ in the documentation and/or other materials provided with the
16
+ distribution.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ You can contact the author at :
31
+ - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
32
+ - LZ4 source repository : http://code.google.com/p/lz4/
33
+ */
34
+ #pragma once
35
+
36
+
37
+ #if defined (__cplusplus)
38
+ extern "C" {
39
+ #endif
40
+
41
+
42
+ int LZ4_compressHC (const char* source, char* dest, int inputSize);
43
+ /*
44
+ LZ4_compressHC :
45
+ return : the number of bytes in compressed buffer dest
46
+ or 0 if compression fails.
47
+ note : destination buffer must be already allocated.
48
+ To avoid any problem, size it to handle worst cases situations (input data not compressible)
49
+ Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h")
50
+ */
51
+
52
+ int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
53
+ /*
54
+ LZ4_compress_limitedOutput() :
55
+ Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
56
+ If it cannot achieve it, compression will stop, and result of the function will be zero.
57
+ This function never writes outside of provided output buffer.
58
+
59
+ inputSize : Max supported value is 1 GB
60
+ maxOutputSize : is maximum allowed size into the destination buffer (which must be already allocated)
61
+ return : the number of output bytes written in buffer 'dest'
62
+ or 0 if compression fails.
63
+ */
64
+
65
+
66
+ /* Note :
67
+ Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license)
68
+ */
69
+
70
+
71
+ /* Advanced Functions */
72
+
73
+ void* LZ4_createHC (const char* inputBuffer);
74
+ int LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize);
75
+ int LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize);
76
+ char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
77
+ int LZ4_freeHC (void* LZ4HC_Data);
78
+
79
+ /*
80
+ These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks.
81
+ In order to achieve this, it is necessary to start creating the LZ4HC Data Structure, thanks to the function :
82
+
83
+ void* LZ4_createHC (const char* inputBuffer);
84
+ The result of the function is the (void*) pointer on the LZ4HC Data Structure.
85
+ This pointer will be needed in all other functions.
86
+ If the pointer returned is NULL, then the allocation has failed, and compression must be aborted.
87
+ The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer.
88
+ The input buffer must be already allocated, and size at least 192KB.
89
+ 'inputBuffer' will also be the 'const char* source' of the first block.
90
+
91
+ All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'.
92
+ To compress each block, use either LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue().
93
+ Their behavior are identical to LZ4_compressHC() or LZ4_compressHC_limitedOutput(),
94
+ but require the LZ4HC Data Structure as their first argument, and check that each block starts right after the previous one.
95
+ If next block does not begin immediately after the previous one, the compression will fail (return 0).
96
+
97
+ When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to :
98
+ char* LZ4_slideInputBufferHC(void* LZ4HC_Data);
99
+ must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer.
100
+ Note that, for this function to work properly, minimum size of an input buffer must be 192KB.
101
+ ==> The memory position where the next input data block must start is provided as the result of the function.
102
+
103
+ Compression can then resume, using LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue(), as usual.
104
+
105
+ When compression is completed, a call to LZ4_freeHC() will release the memory used by the LZ4HC Data Structure.
106
+ */
107
+
108
+
109
+ #if defined (__cplusplus)
110
+ }
111
+ #endif
@@ -0,0 +1,817 @@
1
+ /*
2
+ LZ4 HC - High Compression Mode of LZ4
3
+ Copyright (C) 2011-2013, Yann Collet.
4
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are
8
+ met:
9
+
10
+ * Redistributions of source code must retain the above copyright
11
+ notice, this list of conditions and the following disclaimer.
12
+ * Redistributions in binary form must reproduce the above
13
+ copyright notice, this list of conditions and the following disclaimer
14
+ in the documentation and/or other materials provided with the
15
+ distribution.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ You can contact the author at :
30
+ - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
31
+ - LZ4 source repository : http://code.google.com/p/lz4/
32
+ */
33
+
34
+ //**************************************
35
+ // Memory routines
36
+ //**************************************
37
+ #include <stdlib.h> // calloc, free
38
+ #define ALLOCATOR(s) calloc(1,s)
39
+ #define FREEMEM free
40
+ #include <string.h> // memset, memcpy
41
+ #define MEM_INIT memset
42
+
43
+
44
+ //**************************************
45
+ // CPU Feature Detection
46
+ //**************************************
47
+ // 32 or 64 bits ?
48
+ #if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \
49
+ || defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \
50
+ || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \
51
+ || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) ) // Detects 64 bits mode
52
+ # define LZ4_ARCH64 1
53
+ #else
54
+ # define LZ4_ARCH64 0
55
+ #endif
56
+
57
+ // Little Endian or Big Endian ?
58
+ // Overwrite the #define below if you know your architecture endianess
59
+ #if defined (__GLIBC__)
60
+ # include <endian.h>
61
+ # if (__BYTE_ORDER == __BIG_ENDIAN)
62
+ # define LZ4_BIG_ENDIAN 1
63
+ # endif
64
+ #elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN))
65
+ # define LZ4_BIG_ENDIAN 1
66
+ #elif defined(__sparc) || defined(__sparc__) \
67
+ || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \
68
+ || defined(__hpux) || defined(__hppa) \
69
+ || defined(_MIPSEB) || defined(__s390__)
70
+ # define LZ4_BIG_ENDIAN 1
71
+ #else
72
+ // Little Endian assumed. PDP Endian and other very rare endian format are unsupported.
73
+ #endif
74
+
75
+ // Unaligned memory access is automatically enabled for "common" CPU, such as x86.
76
+ // For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected
77
+ // If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance
78
+ #if defined(__ARM_FEATURE_UNALIGNED)
79
+ # define LZ4_FORCE_UNALIGNED_ACCESS 1
80
+ #endif
81
+
82
+ // Define this parameter if your target system or compiler does not support hardware bit count
83
+ #if defined(_MSC_VER) && defined(_WIN32_WCE) // Visual Studio for Windows CE does not support Hardware bit count
84
+ # define LZ4_FORCE_SW_BITCOUNT
85
+ #endif
86
+
87
+
88
+ //**************************************
89
+ // Compiler Options
90
+ //**************************************
91
+ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
92
+ /* "restrict" is a known keyword */
93
+ #else
94
+ # define restrict // Disable restrict
95
+ #endif
96
+
97
+ #ifdef _MSC_VER // Visual Studio
98
+ # define FORCE_INLINE static __forceinline
99
+ # include <intrin.h> // For Visual 2005
100
+ # if LZ4_ARCH64 // 64-bits
101
+ # pragma intrinsic(_BitScanForward64) // For Visual 2005
102
+ # pragma intrinsic(_BitScanReverse64) // For Visual 2005
103
+ # else // 32-bits
104
+ # pragma intrinsic(_BitScanForward) // For Visual 2005
105
+ # pragma intrinsic(_BitScanReverse) // For Visual 2005
106
+ # endif
107
+ # pragma warning(disable : 4127) // disable: C4127: conditional expression is constant
108
+ # pragma warning(disable : 4701) // disable: C4701: potentially uninitialized local variable used
109
+ #else
110
+ # ifdef __GNUC__
111
+ # define FORCE_INLINE static inline __attribute__((always_inline))
112
+ # else
113
+ # define FORCE_INLINE static inline
114
+ # endif
115
+ #endif
116
+
117
+ #ifdef _MSC_VER // Visual Studio
118
+ # define lz4_bswap16(x) _byteswap_ushort(x)
119
+ #else
120
+ # define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))
121
+ #endif
122
+
123
+
124
+ //**************************************
125
+ // Includes
126
+ //**************************************
127
+ #include "lz4hc.h"
128
+ #include "lz4.h"
129
+
130
+
131
+ //**************************************
132
+ // Basic Types
133
+ //**************************************
134
+ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
135
+ # include <stdint.h>
136
+ typedef uint8_t BYTE;
137
+ typedef uint16_t U16;
138
+ typedef uint32_t U32;
139
+ typedef int32_t S32;
140
+ typedef uint64_t U64;
141
+ #else
142
+ typedef unsigned char BYTE;
143
+ typedef unsigned short U16;
144
+ typedef unsigned int U32;
145
+ typedef signed int S32;
146
+ typedef unsigned long long U64;
147
+ #endif
148
+
149
+ #if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS)
150
+ # define _PACKED __attribute__ ((packed))
151
+ #else
152
+ # define _PACKED
153
+ #endif
154
+
155
+ #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
156
+ # ifdef __IBMC__
157
+ # pragma pack(1)
158
+ # else
159
+ # pragma pack(push, 1)
160
+ # endif
161
+ #endif
162
+
163
+ typedef struct _U16_S { U16 v; } _PACKED U16_S;
164
+ typedef struct _U32_S { U32 v; } _PACKED U32_S;
165
+ typedef struct _U64_S { U64 v; } _PACKED U64_S;
166
+
167
+ #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
168
+ # pragma pack(pop)
169
+ #endif
170
+
171
+ #define A64(x) (((U64_S *)(x))->v)
172
+ #define A32(x) (((U32_S *)(x))->v)
173
+ #define A16(x) (((U16_S *)(x))->v)
174
+
175
+
176
+ //**************************************
177
+ // Constants
178
+ //**************************************
179
+ #define MINMATCH 4
180
+
181
+ #define DICTIONARY_LOGSIZE 16
182
+ #define MAXD (1<<DICTIONARY_LOGSIZE)
183
+ #define MAXD_MASK ((U32)(MAXD - 1))
184
+ #define MAX_DISTANCE (MAXD - 1)
185
+
186
+ #define HASH_LOG (DICTIONARY_LOGSIZE-1)
187
+ #define HASHTABLESIZE (1 << HASH_LOG)
188
+ #define HASH_MASK (HASHTABLESIZE - 1)
189
+
190
+ #define MAX_NB_ATTEMPTS 256
191
+
192
+ #define ML_BITS 4
193
+ #define ML_MASK (size_t)((1U<<ML_BITS)-1)
194
+ #define RUN_BITS (8-ML_BITS)
195
+ #define RUN_MASK ((1U<<RUN_BITS)-1)
196
+
197
+ #define COPYLENGTH 8
198
+ #define LASTLITERALS 5
199
+ #define MFLIMIT (COPYLENGTH+MINMATCH)
200
+ #define MINLENGTH (MFLIMIT+1)
201
+ #define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
202
+
203
+ #define KB *(1U<<10)
204
+ #define MB *(1U<<20)
205
+ #define GB *(1U<<30)
206
+
207
+
208
+ //**************************************
209
+ // Architecture-specific macros
210
+ //**************************************
211
+ #if LZ4_ARCH64 // 64-bit
212
+ # define STEPSIZE 8
213
+ # define LZ4_COPYSTEP(s,d) A64(d) = A64(s); d+=8; s+=8;
214
+ # define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d)
215
+ # define UARCH U64
216
+ # define AARCH A64
217
+ # define HTYPE U32
218
+ # define INITBASE(b,s) const BYTE* const b = s
219
+ #else // 32-bit
220
+ # define STEPSIZE 4
221
+ # define LZ4_COPYSTEP(s,d) A32(d) = A32(s); d+=4; s+=4;
222
+ # define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
223
+ # define UARCH U32
224
+ # define AARCH A32
225
+ //# define HTYPE const BYTE*
226
+ //# define INITBASE(b,s) const int b = 0
227
+ # define HTYPE U32
228
+ # define INITBASE(b,s) const BYTE* const b = s
229
+ #endif
230
+
231
+ #if defined(LZ4_BIG_ENDIAN)
232
+ # define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
233
+ # define LZ4_WRITE_LITTLEENDIAN_16(p,i) { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p+=2; }
234
+ #else // Little Endian
235
+ # define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
236
+ # define LZ4_WRITE_LITTLEENDIAN_16(p,v) { A16(p) = v; p+=2; }
237
+ #endif
238
+
239
+
240
+ //************************************************************
241
+ // Local Types
242
+ //************************************************************
243
+ typedef struct
244
+ {
245
+ const BYTE* inputBuffer;
246
+ const BYTE* base;
247
+ const BYTE* end;
248
+ HTYPE hashTable[HASHTABLESIZE];
249
+ U16 chainTable[MAXD];
250
+ const BYTE* nextToUpdate;
251
+ } LZ4HC_Data_Structure;
252
+
253
+
254
+ //**************************************
255
+ // Macros
256
+ //**************************************
257
+ #define LZ4_WILDCOPY(s,d,e) do { LZ4_COPYPACKET(s,d) } while (d<e);
258
+ #define LZ4_BLINDCOPY(s,d,l) { BYTE* e=d+l; LZ4_WILDCOPY(s,d,e); d=e; }
259
+ #define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
260
+ #define HASH_VALUE(p) HASH_FUNCTION(A32(p))
261
+ #define HASH_POINTER(p) (HashTable[HASH_VALUE(p)] + base)
262
+ #define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK]
263
+ #define GETNEXT(p) ((p) - (size_t)DELTANEXT(p))
264
+
265
+
266
+ //**************************************
267
+ // Private functions
268
+ //**************************************
269
+ #if LZ4_ARCH64
270
+
271
+ FORCE_INLINE int LZ4_NbCommonBytes (register U64 val)
272
+ {
273
+ #if defined(LZ4_BIG_ENDIAN)
274
+ # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
275
+ unsigned long r = 0;
276
+ _BitScanReverse64( &r, val );
277
+ return (int)(r>>3);
278
+ # elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
279
+ return (__builtin_clzll(val) >> 3);
280
+ # else
281
+ int r;
282
+ if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
283
+ if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
284
+ r += (!val);
285
+ return r;
286
+ # endif
287
+ #else
288
+ # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
289
+ unsigned long r = 0;
290
+ _BitScanForward64( &r, val );
291
+ return (int)(r>>3);
292
+ # elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
293
+ return (__builtin_ctzll(val) >> 3);
294
+ # else
295
+ 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 };
296
+ return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];
297
+ # endif
298
+ #endif
299
+ }
300
+
301
+ #else
302
+
303
+ FORCE_INLINE int LZ4_NbCommonBytes (register U32 val)
304
+ {
305
+ #if defined(LZ4_BIG_ENDIAN)
306
+ # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
307
+ unsigned long r;
308
+ _BitScanReverse( &r, val );
309
+ return (int)(r>>3);
310
+ # elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
311
+ return (__builtin_clz(val) >> 3);
312
+ # else
313
+ int r;
314
+ if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
315
+ r += (!val);
316
+ return r;
317
+ # endif
318
+ #else
319
+ # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
320
+ unsigned long r;
321
+ _BitScanForward( &r, val );
322
+ return (int)(r>>3);
323
+ # elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
324
+ return (__builtin_ctz(val) >> 3);
325
+ # else
326
+ 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 };
327
+ return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
328
+ # endif
329
+ #endif
330
+ }
331
+
332
+ #endif
333
+
334
+
335
+ FORCE_INLINE void LZ4_initHC (LZ4HC_Data_Structure* hc4, const BYTE* base)
336
+ {
337
+ MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
338
+ MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
339
+ hc4->nextToUpdate = base + 1;
340
+ hc4->base = base;
341
+ hc4->inputBuffer = base;
342
+ hc4->end = base;
343
+ }
344
+
345
+
346
+ void* LZ4_createHC (const char* inputBuffer)
347
+ {
348
+ void* hc4 = ALLOCATOR(sizeof(LZ4HC_Data_Structure));
349
+ LZ4_initHC ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer);
350
+ return hc4;
351
+ }
352
+
353
+
354
+ int LZ4_freeHC (void* LZ4HC_Data)
355
+ {
356
+ FREEMEM(LZ4HC_Data);
357
+ return (0);
358
+ }
359
+
360
+
361
+ // Update chains up to ip (excluded)
362
+ FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
363
+ {
364
+ U16* chainTable = hc4->chainTable;
365
+ HTYPE* HashTable = hc4->hashTable;
366
+ INITBASE(base,hc4->base);
367
+
368
+ while(hc4->nextToUpdate < ip)
369
+ {
370
+ const BYTE* const p = hc4->nextToUpdate;
371
+ size_t delta = (p) - HASH_POINTER(p);
372
+ if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
373
+ DELTANEXT(p) = (U16)delta;
374
+ HashTable[HASH_VALUE(p)] = (HTYPE)((p) - base);
375
+ hc4->nextToUpdate++;
376
+ }
377
+ }
378
+
379
+
380
+ char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
381
+ {
382
+ LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data;
383
+ U32 distance = (U32)(hc4->end - hc4->inputBuffer) - 64 KB;
384
+ distance = (distance >> 16) << 16; // Must be a multiple of 64 KB
385
+ LZ4HC_Insert(hc4, hc4->end - MINMATCH);
386
+ memcpy((void*)(hc4->end - 64 KB - distance), (const void*)(hc4->end - 64 KB), 64 KB);
387
+ hc4->nextToUpdate -= distance;
388
+ hc4->base -= distance;
389
+ if ((U32)(hc4->inputBuffer - hc4->base) > 1 GB + 64 KB) // Avoid overflow
390
+ {
391
+ int i;
392
+ hc4->base += 1 GB;
393
+ for (i=0; i<HASHTABLESIZE; i++) hc4->hashTable[i] -= 1 GB;
394
+ }
395
+ hc4->end -= distance;
396
+ return (char*)(hc4->end);
397
+ }
398
+
399
+
400
+ FORCE_INLINE size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, const BYTE* const matchlimit)
401
+ {
402
+ const BYTE* p1t = p1;
403
+
404
+ while (p1t<matchlimit-(STEPSIZE-1))
405
+ {
406
+ UARCH diff = AARCH(p2) ^ AARCH(p1t);
407
+ if (!diff) { p1t+=STEPSIZE; p2+=STEPSIZE; continue; }
408
+ p1t += LZ4_NbCommonBytes(diff);
409
+ return (p1t - p1);
410
+ }
411
+ if (LZ4_ARCH64) if ((p1t<(matchlimit-3)) && (A32(p2) == A32(p1t))) { p1t+=4; p2+=4; }
412
+ if ((p1t<(matchlimit-1)) && (A16(p2) == A16(p1t))) { p1t+=2; p2+=2; }
413
+ if ((p1t<matchlimit) && (*p2 == *p1t)) p1t++;
414
+ return (p1t - p1);
415
+ }
416
+
417
+
418
+ FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* const matchlimit, const BYTE** matchpos)
419
+ {
420
+ U16* const chainTable = hc4->chainTable;
421
+ HTYPE* const HashTable = hc4->hashTable;
422
+ const BYTE* ref;
423
+ INITBASE(base,hc4->base);
424
+ int nbAttempts=MAX_NB_ATTEMPTS;
425
+ size_t repl=0, ml=0;
426
+ U16 delta=0; // useless assignment, to remove an uninitialization warning
427
+
428
+ // HC4 match finder
429
+ LZ4HC_Insert(hc4, ip);
430
+ ref = HASH_POINTER(ip);
431
+
432
+ #define REPEAT_OPTIMIZATION
433
+ #ifdef REPEAT_OPTIMIZATION
434
+ // Detect repetitive sequences of length <= 4
435
+ if ((U32)(ip-ref) <= 4) // potential repetition
436
+ {
437
+ if (A32(ref) == A32(ip)) // confirmed
438
+ {
439
+ delta = (U16)(ip-ref);
440
+ repl = ml = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH;
441
+ *matchpos = ref;
442
+ }
443
+ ref = GETNEXT(ref);
444
+ }
445
+ #endif
446
+
447
+ while (((U32)(ip-ref) <= MAX_DISTANCE) && (nbAttempts))
448
+ {
449
+ nbAttempts--;
450
+ if (*(ref+ml) == *(ip+ml))
451
+ if (A32(ref) == A32(ip))
452
+ {
453
+ size_t mlt = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH;
454
+ if (mlt > ml) { ml = mlt; *matchpos = ref; }
455
+ }
456
+ ref = GETNEXT(ref);
457
+ }
458
+
459
+ #ifdef REPEAT_OPTIMIZATION
460
+ // Complete table
461
+ if (repl)
462
+ {
463
+ const BYTE* ptr = ip;
464
+ const BYTE* end;
465
+
466
+ end = ip + repl - (MINMATCH-1);
467
+ while(ptr < end-delta)
468
+ {
469
+ DELTANEXT(ptr) = delta; // Pre-Load
470
+ ptr++;
471
+ }
472
+ do
473
+ {
474
+ DELTANEXT(ptr) = delta;
475
+ HashTable[HASH_VALUE(ptr)] = (HTYPE)((ptr) - base); // Head of chain
476
+ ptr++;
477
+ } while(ptr < end);
478
+ hc4->nextToUpdate = end;
479
+ }
480
+ #endif
481
+
482
+ return (int)ml;
483
+ }
484
+
485
+
486
+ FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* startLimit, const BYTE* matchlimit, int longest, const BYTE** matchpos, const BYTE** startpos)
487
+ {
488
+ U16* const chainTable = hc4->chainTable;
489
+ HTYPE* const HashTable = hc4->hashTable;
490
+ INITBASE(base,hc4->base);
491
+ const BYTE* ref;
492
+ int nbAttempts = MAX_NB_ATTEMPTS;
493
+ int delta = (int)(ip-startLimit);
494
+
495
+ // First Match
496
+ LZ4HC_Insert(hc4, ip);
497
+ ref = HASH_POINTER(ip);
498
+
499
+ while (((U32)(ip-ref) <= MAX_DISTANCE) && (nbAttempts))
500
+ {
501
+ nbAttempts--;
502
+ if (*(startLimit + longest) == *(ref - delta + longest))
503
+ if (A32(ref) == A32(ip))
504
+ {
505
+ #if 1
506
+ const BYTE* reft = ref+MINMATCH;
507
+ const BYTE* ipt = ip+MINMATCH;
508
+ const BYTE* startt = ip;
509
+
510
+ while (ipt<matchlimit-(STEPSIZE-1))
511
+ {
512
+ UARCH diff = AARCH(reft) ^ AARCH(ipt);
513
+ if (!diff) { ipt+=STEPSIZE; reft+=STEPSIZE; continue; }
514
+ ipt += LZ4_NbCommonBytes(diff);
515
+ goto _endCount;
516
+ }
517
+ if (LZ4_ARCH64) if ((ipt<(matchlimit-3)) && (A32(reft) == A32(ipt))) { ipt+=4; reft+=4; }
518
+ if ((ipt<(matchlimit-1)) && (A16(reft) == A16(ipt))) { ipt+=2; reft+=2; }
519
+ if ((ipt<matchlimit) && (*reft == *ipt)) ipt++;
520
+ _endCount:
521
+ reft = ref;
522
+ #else
523
+ // Easier for code maintenance, but unfortunately slower too
524
+ const BYTE* startt = ip;
525
+ const BYTE* reft = ref;
526
+ const BYTE* ipt = ip + MINMATCH + LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit);
527
+ #endif
528
+
529
+ while ((startt>startLimit) && (reft > hc4->inputBuffer) && (startt[-1] == reft[-1])) {startt--; reft--;}
530
+
531
+ if ((ipt-startt) > longest)
532
+ {
533
+ longest = (int)(ipt-startt);
534
+ *matchpos = reft;
535
+ *startpos = startt;
536
+ }
537
+ }
538
+ ref = GETNEXT(ref);
539
+ }
540
+
541
+ return longest;
542
+ }
543
+
544
+
545
+ typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
546
+
547
+ FORCE_INLINE int LZ4HC_encodeSequence (
548
+ const BYTE** ip,
549
+ BYTE** op,
550
+ const BYTE** anchor,
551
+ int matchLength,
552
+ const BYTE* ref,
553
+ limitedOutput_directive limitedOutputBuffer,
554
+ BYTE* oend)
555
+ {
556
+ int length;
557
+ BYTE* token;
558
+
559
+ // Encode Literal length
560
+ length = (int)(*ip - *anchor);
561
+ token = (*op)++;
562
+ if ((limitedOutputBuffer) && ((*op + length + (2 + 1 + LASTLITERALS) + (length>>8)) > oend)) return 1; // Check output limit
563
+ if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; }
564
+ else *token = (BYTE)(length<<ML_BITS);
565
+
566
+ // Copy Literals
567
+ LZ4_BLINDCOPY(*anchor, *op, length);
568
+
569
+ // Encode Offset
570
+ LZ4_WRITE_LITTLEENDIAN_16(*op,(U16)(*ip-ref));
571
+
572
+ // Encode MatchLength
573
+ length = (int)(matchLength-MINMATCH);
574
+ if ((limitedOutputBuffer) && (*op + (1 + LASTLITERALS) + (length>>8) > oend)) return 1; // Check output limit
575
+ if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; }
576
+ else *token += (BYTE)(length);
577
+
578
+ // Prepare next loop
579
+ *ip += matchLength;
580
+ *anchor = *ip;
581
+
582
+ return 0;
583
+ }
584
+
585
+
586
+ static int LZ4HC_compress_generic (
587
+ void* ctxvoid,
588
+ const char* source,
589
+ char* dest,
590
+ int inputSize,
591
+ int maxOutputSize,
592
+ limitedOutput_directive limit
593
+ )
594
+ {
595
+ LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid;
596
+ const BYTE* ip = (const BYTE*) source;
597
+ const BYTE* anchor = ip;
598
+ const BYTE* const iend = ip + inputSize;
599
+ const BYTE* const mflimit = iend - MFLIMIT;
600
+ const BYTE* const matchlimit = (iend - LASTLITERALS);
601
+
602
+ BYTE* op = (BYTE*) dest;
603
+ BYTE* const oend = op + maxOutputSize;
604
+
605
+ int ml, ml2, ml3, ml0;
606
+ const BYTE* ref=NULL;
607
+ const BYTE* start2=NULL;
608
+ const BYTE* ref2=NULL;
609
+ const BYTE* start3=NULL;
610
+ const BYTE* ref3=NULL;
611
+ const BYTE* start0;
612
+ const BYTE* ref0;
613
+
614
+
615
+ // Ensure blocks follow each other
616
+ if (ip != ctx->end) return 0;
617
+ ctx->end += inputSize;
618
+
619
+ ip++;
620
+
621
+ // Main Loop
622
+ while (ip < mflimit)
623
+ {
624
+ ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref));
625
+ if (!ml) { ip++; continue; }
626
+
627
+ // saved, in case we would skip too much
628
+ start0 = ip;
629
+ ref0 = ref;
630
+ ml0 = ml;
631
+
632
+ _Search2:
633
+ if (ip+ml < mflimit)
634
+ ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2);
635
+ else ml2 = ml;
636
+
637
+ if (ml2 == ml) // No better match
638
+ {
639
+ if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
640
+ continue;
641
+ }
642
+
643
+ if (start0 < ip)
644
+ {
645
+ if (start2 < ip + ml0) // empirical
646
+ {
647
+ ip = start0;
648
+ ref = ref0;
649
+ ml = ml0;
650
+ }
651
+ }
652
+
653
+ // Here, start0==ip
654
+ if ((start2 - ip) < 3) // First Match too small : removed
655
+ {
656
+ ml = ml2;
657
+ ip = start2;
658
+ ref =ref2;
659
+ goto _Search2;
660
+ }
661
+
662
+ _Search3:
663
+ // Currently we have :
664
+ // ml2 > ml1, and
665
+ // ip1+3 <= ip2 (usually < ip1+ml1)
666
+ if ((start2 - ip) < OPTIMAL_ML)
667
+ {
668
+ int correction;
669
+ int new_ml = ml;
670
+ if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
671
+ if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
672
+ correction = new_ml - (int)(start2 - ip);
673
+ if (correction > 0)
674
+ {
675
+ start2 += correction;
676
+ ref2 += correction;
677
+ ml2 -= correction;
678
+ }
679
+ }
680
+ // Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18)
681
+
682
+ if (start2 + ml2 < mflimit)
683
+ ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3);
684
+ else ml3 = ml2;
685
+
686
+ if (ml3 == ml2) // No better match : 2 sequences to encode
687
+ {
688
+ // ip & ref are known; Now for ml
689
+ if (start2 < ip+ml) ml = (int)(start2 - ip);
690
+ // Now, encode 2 sequences
691
+ if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
692
+ ip = start2;
693
+ if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0;
694
+ continue;
695
+ }
696
+
697
+ if (start3 < ip+ml+3) // Not enough space for match 2 : remove it
698
+ {
699
+ if (start3 >= (ip+ml)) // can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1
700
+ {
701
+ if (start2 < ip+ml)
702
+ {
703
+ int correction = (int)(ip+ml - start2);
704
+ start2 += correction;
705
+ ref2 += correction;
706
+ ml2 -= correction;
707
+ if (ml2 < MINMATCH)
708
+ {
709
+ start2 = start3;
710
+ ref2 = ref3;
711
+ ml2 = ml3;
712
+ }
713
+ }
714
+
715
+ if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
716
+ ip = start3;
717
+ ref = ref3;
718
+ ml = ml3;
719
+
720
+ start0 = start2;
721
+ ref0 = ref2;
722
+ ml0 = ml2;
723
+ goto _Search2;
724
+ }
725
+
726
+ start2 = start3;
727
+ ref2 = ref3;
728
+ ml2 = ml3;
729
+ goto _Search3;
730
+ }
731
+
732
+ // OK, now we have 3 ascending matches; let's write at least the first one
733
+ // ip & ref are known; Now for ml
734
+ if (start2 < ip+ml)
735
+ {
736
+ if ((start2 - ip) < (int)ML_MASK)
737
+ {
738
+ int correction;
739
+ if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
740
+ if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
741
+ correction = ml - (int)(start2 - ip);
742
+ if (correction > 0)
743
+ {
744
+ start2 += correction;
745
+ ref2 += correction;
746
+ ml2 -= correction;
747
+ }
748
+ }
749
+ else
750
+ {
751
+ ml = (int)(start2 - ip);
752
+ }
753
+ }
754
+ if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
755
+
756
+ ip = start2;
757
+ ref = ref2;
758
+ ml = ml2;
759
+
760
+ start2 = start3;
761
+ ref2 = ref3;
762
+ ml2 = ml3;
763
+
764
+ goto _Search3;
765
+
766
+ }
767
+
768
+ // Encode Last Literals
769
+ {
770
+ int lastRun = (int)(iend - anchor);
771
+ if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; // Check output limit
772
+ if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
773
+ else *op++ = (BYTE)(lastRun<<ML_BITS);
774
+ memcpy(op, anchor, iend - anchor);
775
+ op += iend-anchor;
776
+ }
777
+
778
+ // End
779
+ return (int) (((char*)op)-dest);
780
+ }
781
+
782
+
783
+ int LZ4_compressHC(const char* source, char* dest, int inputSize)
784
+ {
785
+ void* ctx = LZ4_createHC(source);
786
+ int result;
787
+ if (ctx==NULL) return 0;
788
+
789
+ result = LZ4HC_compress_generic (ctx, source, dest, inputSize, 0, noLimit);
790
+
791
+ LZ4_freeHC(ctx);
792
+ return result;
793
+ }
794
+
795
+ int LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize)
796
+ {
797
+ return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, noLimit);
798
+ }
799
+
800
+
801
+ int LZ4_compressHC_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize)
802
+ {
803
+ void* ctx = LZ4_createHC(source);
804
+ int result;
805
+ if (ctx==NULL) return 0;
806
+
807
+ result = LZ4HC_compress_generic (ctx, source, dest, inputSize, maxOutputSize, limitedOutput);
808
+
809
+ LZ4_freeHC(ctx);
810
+ return result;
811
+ }
812
+
813
+ int LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize)
814
+ {
815
+ return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, limitedOutput);
816
+ }
817
+