1eb7fbc25SPierre Schweitzer /*
2*06042735SVincent Franchomme  * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3eb7fbc25SPierre Schweitzer  * All rights reserved.
4eb7fbc25SPierre Schweitzer  *
5eb7fbc25SPierre Schweitzer  * This source code is licensed under both the BSD-style license (found in the
6eb7fbc25SPierre Schweitzer  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7eb7fbc25SPierre Schweitzer  * in the COPYING file in the root directory of this source tree).
8eb7fbc25SPierre Schweitzer  * You may select, at your option, one of the above-listed licenses.
9eb7fbc25SPierre Schweitzer  */
10eb7fbc25SPierre Schweitzer 
11eb7fbc25SPierre Schweitzer #ifndef ZSTD_CCOMMON_H_MODULE
12eb7fbc25SPierre Schweitzer #define ZSTD_CCOMMON_H_MODULE
13eb7fbc25SPierre Schweitzer 
14eb7fbc25SPierre Schweitzer /* this module contains definitions which must be identical
15eb7fbc25SPierre Schweitzer  * across compression, decompression and dictBuilder.
16eb7fbc25SPierre Schweitzer  * It also contains a few functions useful to at least 2 of them
17eb7fbc25SPierre Schweitzer  * and which benefit from being inlined */
18eb7fbc25SPierre Schweitzer 
19eb7fbc25SPierre Schweitzer /*-*************************************
20eb7fbc25SPierre Schweitzer *  Dependencies
21eb7fbc25SPierre Schweitzer ***************************************/
22*06042735SVincent Franchomme #ifdef __aarch64__
23*06042735SVincent Franchomme #include <arm_neon.h>
24*06042735SVincent Franchomme #endif
25eb7fbc25SPierre Schweitzer #include "compiler.h"
26eb7fbc25SPierre Schweitzer #include "mem.h"
27eb7fbc25SPierre Schweitzer #include "debug.h"                 /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
28eb7fbc25SPierre Schweitzer #include "error_private.h"
29eb7fbc25SPierre Schweitzer #define ZSTD_STATIC_LINKING_ONLY
30eb7fbc25SPierre Schweitzer #include "zstd.h"
31eb7fbc25SPierre Schweitzer #define FSE_STATIC_LINKING_ONLY
32eb7fbc25SPierre Schweitzer #include "fse.h"
33eb7fbc25SPierre Schweitzer #define HUF_STATIC_LINKING_ONLY
34eb7fbc25SPierre Schweitzer #include "huf.h"
35eb7fbc25SPierre Schweitzer #ifndef XXH_STATIC_LINKING_ONLY
36eb7fbc25SPierre Schweitzer #  define XXH_STATIC_LINKING_ONLY  /* XXH64_state_t */
37eb7fbc25SPierre Schweitzer #endif
38194ea909SVictor Perevertkin #include "../xxhash.h"                /* XXH_reset, update, digest */
39eb7fbc25SPierre Schweitzer 
40eb7fbc25SPierre Schweitzer #if defined (__cplusplus)
41eb7fbc25SPierre Schweitzer extern "C" {
42eb7fbc25SPierre Schweitzer #endif
43eb7fbc25SPierre Schweitzer 
44eb7fbc25SPierre Schweitzer /* ---- static assert (debug) --- */
45eb7fbc25SPierre Schweitzer #define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
46*06042735SVincent Franchomme #define ZSTD_isError ERR_isError   /* for inlining */
47*06042735SVincent Franchomme #define FSE_isError  ERR_isError
48*06042735SVincent Franchomme #define HUF_isError  ERR_isError
49eb7fbc25SPierre Schweitzer 
50eb7fbc25SPierre Schweitzer 
51eb7fbc25SPierre Schweitzer /*-*************************************
52eb7fbc25SPierre Schweitzer *  shared macros
53eb7fbc25SPierre Schweitzer ***************************************/
54eb7fbc25SPierre Schweitzer #undef MIN
55eb7fbc25SPierre Schweitzer #undef MAX
56eb7fbc25SPierre Schweitzer #define MIN(a,b) ((a)<(b) ? (a) : (b))
57eb7fbc25SPierre Schweitzer #define MAX(a,b) ((a)>(b) ? (a) : (b))
58*06042735SVincent Franchomme 
59*06042735SVincent Franchomme /**
60*06042735SVincent Franchomme  * Ignore: this is an internal helper.
61*06042735SVincent Franchomme  *
62*06042735SVincent Franchomme  * This is a helper function to help force C99-correctness during compilation.
63*06042735SVincent Franchomme  * Under strict compilation modes, variadic macro arguments can't be empty.
64*06042735SVincent Franchomme  * However, variadic function arguments can be. Using a function therefore lets
65*06042735SVincent Franchomme  * us statically check that at least one (string) argument was passed,
66*06042735SVincent Franchomme  * independent of the compilation flags.
67*06042735SVincent Franchomme  */
68*06042735SVincent Franchomme static INLINE_KEYWORD UNUSED_ATTR
_force_has_format_string(const char * format,...)69*06042735SVincent Franchomme void _force_has_format_string(const char *format, ...) {
70*06042735SVincent Franchomme   (void)format;
71*06042735SVincent Franchomme }
72*06042735SVincent Franchomme 
73*06042735SVincent Franchomme /**
74*06042735SVincent Franchomme  * Ignore: this is an internal helper.
75*06042735SVincent Franchomme  *
76*06042735SVincent Franchomme  * We want to force this function invocation to be syntactically correct, but
77*06042735SVincent Franchomme  * we don't want to force runtime evaluation of its arguments.
78*06042735SVincent Franchomme  */
79*06042735SVincent Franchomme #define _FORCE_HAS_FORMAT_STRING(...) \
80*06042735SVincent Franchomme   if (0) { \
81*06042735SVincent Franchomme     _force_has_format_string(__VA_ARGS__); \
82*06042735SVincent Franchomme   }
83*06042735SVincent Franchomme 
84*06042735SVincent Franchomme /**
85*06042735SVincent Franchomme  * Return the specified error if the condition evaluates to true.
86*06042735SVincent Franchomme  *
87*06042735SVincent Franchomme  * In debug modes, prints additional information.
88*06042735SVincent Franchomme  * In order to do that (particularly, printing the conditional that failed),
89*06042735SVincent Franchomme  * this can't just wrap RETURN_ERROR().
90*06042735SVincent Franchomme  */
91*06042735SVincent Franchomme #define RETURN_ERROR_IF(cond, err, ...) \
92*06042735SVincent Franchomme   if (cond) { \
93*06042735SVincent Franchomme     RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
94*06042735SVincent Franchomme            __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \
95*06042735SVincent Franchomme     _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
96*06042735SVincent Franchomme     RAWLOG(3, ": " __VA_ARGS__); \
97*06042735SVincent Franchomme     RAWLOG(3, "\n"); \
98*06042735SVincent Franchomme     return ERROR(err); \
99*06042735SVincent Franchomme   }
100*06042735SVincent Franchomme 
101*06042735SVincent Franchomme /**
102*06042735SVincent Franchomme  * Unconditionally return the specified error.
103*06042735SVincent Franchomme  *
104*06042735SVincent Franchomme  * In debug modes, prints additional information.
105*06042735SVincent Franchomme  */
106*06042735SVincent Franchomme #define RETURN_ERROR(err, ...) \
107*06042735SVincent Franchomme   do { \
108*06042735SVincent Franchomme     RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
109*06042735SVincent Franchomme            __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \
110*06042735SVincent Franchomme     _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
111*06042735SVincent Franchomme     RAWLOG(3, ": " __VA_ARGS__); \
112*06042735SVincent Franchomme     RAWLOG(3, "\n"); \
113*06042735SVincent Franchomme     return ERROR(err); \
114*06042735SVincent Franchomme   } while(0);
115*06042735SVincent Franchomme 
116*06042735SVincent Franchomme /**
117*06042735SVincent Franchomme  * If the provided expression evaluates to an error code, returns that error code.
118*06042735SVincent Franchomme  *
119*06042735SVincent Franchomme  * In debug modes, prints additional information.
120*06042735SVincent Franchomme  */
121*06042735SVincent Franchomme #define FORWARD_IF_ERROR(err, ...) \
122*06042735SVincent Franchomme   do { \
123*06042735SVincent Franchomme     size_t const err_code = (err); \
124*06042735SVincent Franchomme     if (ERR_isError(err_code)) { \
125*06042735SVincent Franchomme       RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
126*06042735SVincent Franchomme              __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \
127*06042735SVincent Franchomme       _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
128*06042735SVincent Franchomme       RAWLOG(3, ": " __VA_ARGS__); \
129*06042735SVincent Franchomme       RAWLOG(3, "\n"); \
130*06042735SVincent Franchomme       return err_code; \
131*06042735SVincent Franchomme     } \
132*06042735SVincent Franchomme   } while(0);
133eb7fbc25SPierre Schweitzer 
134eb7fbc25SPierre Schweitzer 
135eb7fbc25SPierre Schweitzer /*-*************************************
136eb7fbc25SPierre Schweitzer *  Common constants
137eb7fbc25SPierre Schweitzer ***************************************/
138eb7fbc25SPierre Schweitzer #define ZSTD_OPT_NUM    (1<<12)
139eb7fbc25SPierre Schweitzer 
140eb7fbc25SPierre Schweitzer #define ZSTD_REP_NUM      3                 /* number of repcodes */
141eb7fbc25SPierre Schweitzer #define ZSTD_REP_MOVE     (ZSTD_REP_NUM-1)
142eb7fbc25SPierre Schweitzer static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
143eb7fbc25SPierre Schweitzer 
144eb7fbc25SPierre Schweitzer #define KB *(1 <<10)
145eb7fbc25SPierre Schweitzer #define MB *(1 <<20)
146eb7fbc25SPierre Schweitzer #define GB *(1U<<30)
147eb7fbc25SPierre Schweitzer 
148eb7fbc25SPierre Schweitzer #define BIT7 128
149eb7fbc25SPierre Schweitzer #define BIT6  64
150eb7fbc25SPierre Schweitzer #define BIT5  32
151eb7fbc25SPierre Schweitzer #define BIT4  16
152eb7fbc25SPierre Schweitzer #define BIT1   2
153eb7fbc25SPierre Schweitzer #define BIT0   1
154eb7fbc25SPierre Schweitzer 
155eb7fbc25SPierre Schweitzer #define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
156eb7fbc25SPierre Schweitzer static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
157eb7fbc25SPierre Schweitzer static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
158eb7fbc25SPierre Schweitzer 
159eb7fbc25SPierre Schweitzer #define ZSTD_FRAMEIDSIZE 4   /* magic number size */
160eb7fbc25SPierre Schweitzer 
161eb7fbc25SPierre Schweitzer #define ZSTD_BLOCKHEADERSIZE 3   /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
162eb7fbc25SPierre Schweitzer static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
163eb7fbc25SPierre Schweitzer typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
164eb7fbc25SPierre Schweitzer 
165*06042735SVincent Franchomme #define ZSTD_FRAMECHECKSUMSIZE 4
166*06042735SVincent Franchomme 
167eb7fbc25SPierre Schweitzer #define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
168eb7fbc25SPierre Schweitzer #define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */)   /* for a non-null block */
169eb7fbc25SPierre Schweitzer 
170eb7fbc25SPierre Schweitzer #define HufLog 12
171eb7fbc25SPierre Schweitzer typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
172eb7fbc25SPierre Schweitzer 
173eb7fbc25SPierre Schweitzer #define LONGNBSEQ 0x7F00
174eb7fbc25SPierre Schweitzer 
175eb7fbc25SPierre Schweitzer #define MINMATCH 3
176eb7fbc25SPierre Schweitzer 
177eb7fbc25SPierre Schweitzer #define Litbits  8
178eb7fbc25SPierre Schweitzer #define MaxLit ((1<<Litbits) - 1)
179eb7fbc25SPierre Schweitzer #define MaxML   52
180eb7fbc25SPierre Schweitzer #define MaxLL   35
181eb7fbc25SPierre Schweitzer #define DefaultMaxOff 28
182eb7fbc25SPierre Schweitzer #define MaxOff  31
183eb7fbc25SPierre Schweitzer #define MaxSeq MAX(MaxLL, MaxML)   /* Assumption : MaxOff < MaxLL,MaxML */
184eb7fbc25SPierre Schweitzer #define MLFSELog    9
185eb7fbc25SPierre Schweitzer #define LLFSELog    9
186eb7fbc25SPierre Schweitzer #define OffFSELog   8
187eb7fbc25SPierre Schweitzer #define MaxFSELog  MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
188eb7fbc25SPierre Schweitzer 
189eb7fbc25SPierre Schweitzer static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
190eb7fbc25SPierre Schweitzer                                       0, 0, 0, 0, 0, 0, 0, 0,
191eb7fbc25SPierre Schweitzer                                       1, 1, 1, 1, 2, 2, 3, 3,
192eb7fbc25SPierre Schweitzer                                       4, 6, 7, 8, 9,10,11,12,
193eb7fbc25SPierre Schweitzer                                      13,14,15,16 };
194eb7fbc25SPierre Schweitzer static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2,
195eb7fbc25SPierre Schweitzer                                              2, 2, 2, 2, 2, 1, 1, 1,
196eb7fbc25SPierre Schweitzer                                              2, 2, 2, 2, 2, 2, 2, 2,
197eb7fbc25SPierre Schweitzer                                              2, 3, 2, 1, 1, 1, 1, 1,
198eb7fbc25SPierre Schweitzer                                             -1,-1,-1,-1 };
199eb7fbc25SPierre Schweitzer #define LL_DEFAULTNORMLOG 6  /* for static allocation */
200eb7fbc25SPierre Schweitzer static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
201eb7fbc25SPierre Schweitzer 
202eb7fbc25SPierre Schweitzer static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
203eb7fbc25SPierre Schweitzer                                       0, 0, 0, 0, 0, 0, 0, 0,
204eb7fbc25SPierre Schweitzer                                       0, 0, 0, 0, 0, 0, 0, 0,
205eb7fbc25SPierre Schweitzer                                       0, 0, 0, 0, 0, 0, 0, 0,
206eb7fbc25SPierre Schweitzer                                       1, 1, 1, 1, 2, 2, 3, 3,
207eb7fbc25SPierre Schweitzer                                       4, 4, 5, 7, 8, 9,10,11,
208eb7fbc25SPierre Schweitzer                                      12,13,14,15,16 };
209eb7fbc25SPierre Schweitzer static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2,
210eb7fbc25SPierre Schweitzer                                              2, 1, 1, 1, 1, 1, 1, 1,
211eb7fbc25SPierre Schweitzer                                              1, 1, 1, 1, 1, 1, 1, 1,
212eb7fbc25SPierre Schweitzer                                              1, 1, 1, 1, 1, 1, 1, 1,
213eb7fbc25SPierre Schweitzer                                              1, 1, 1, 1, 1, 1, 1, 1,
214eb7fbc25SPierre Schweitzer                                              1, 1, 1, 1, 1, 1,-1,-1,
215eb7fbc25SPierre Schweitzer                                             -1,-1,-1,-1,-1 };
216eb7fbc25SPierre Schweitzer #define ML_DEFAULTNORMLOG 6  /* for static allocation */
217eb7fbc25SPierre Schweitzer static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
218eb7fbc25SPierre Schweitzer 
219eb7fbc25SPierre Schweitzer static const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2,
220eb7fbc25SPierre Schweitzer                                                      2, 1, 1, 1, 1, 1, 1, 1,
221eb7fbc25SPierre Schweitzer                                                      1, 1, 1, 1, 1, 1, 1, 1,
222eb7fbc25SPierre Schweitzer                                                     -1,-1,-1,-1,-1 };
223eb7fbc25SPierre Schweitzer #define OF_DEFAULTNORMLOG 5  /* for static allocation */
224eb7fbc25SPierre Schweitzer static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
225eb7fbc25SPierre Schweitzer 
226eb7fbc25SPierre Schweitzer 
227eb7fbc25SPierre Schweitzer /*-*******************************************
228eb7fbc25SPierre Schweitzer *  Shared functions to include for inlining
229eb7fbc25SPierre Schweitzer *********************************************/
ZSTD_copy8(void * dst,const void * src)230*06042735SVincent Franchomme static void ZSTD_copy8(void* dst, const void* src) {
231*06042735SVincent Franchomme #ifdef __aarch64__
232*06042735SVincent Franchomme     vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
233*06042735SVincent Franchomme #else
234*06042735SVincent Franchomme     memcpy(dst, src, 8);
235*06042735SVincent Franchomme #endif
236*06042735SVincent Franchomme }
237*06042735SVincent Franchomme 
238eb7fbc25SPierre Schweitzer #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
ZSTD_copy16(void * dst,const void * src)239*06042735SVincent Franchomme static void ZSTD_copy16(void* dst, const void* src) {
240*06042735SVincent Franchomme #ifdef __aarch64__
241*06042735SVincent Franchomme     vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
242*06042735SVincent Franchomme #else
243*06042735SVincent Franchomme     memcpy(dst, src, 16);
244*06042735SVincent Franchomme #endif
245*06042735SVincent Franchomme }
246*06042735SVincent Franchomme #define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
247*06042735SVincent Franchomme 
248*06042735SVincent Franchomme #define WILDCOPY_OVERLENGTH 32
249*06042735SVincent Franchomme #define WILDCOPY_VECLEN 16
250*06042735SVincent Franchomme 
251*06042735SVincent Franchomme typedef enum {
252*06042735SVincent Franchomme     ZSTD_no_overlap,
253*06042735SVincent Franchomme     ZSTD_overlap_src_before_dst
254*06042735SVincent Franchomme     /*  ZSTD_overlap_dst_before_src, */
255*06042735SVincent Franchomme } ZSTD_overlap_e;
256eb7fbc25SPierre Schweitzer 
257eb7fbc25SPierre Schweitzer /*! ZSTD_wildcopy() :
258*06042735SVincent Franchomme  *  Custom version of memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
259*06042735SVincent Franchomme  *  @param ovtype controls the overlap detection
260*06042735SVincent Franchomme  *         - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
261*06042735SVincent Franchomme  *         - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
262*06042735SVincent Franchomme  *           The src buffer must be before the dst buffer.
263*06042735SVincent Franchomme  */
264*06042735SVincent Franchomme MEM_STATIC FORCE_INLINE_ATTR
ZSTD_wildcopy(void * dst,const void * src,ptrdiff_t length,ZSTD_overlap_e const ovtype)265*06042735SVincent Franchomme void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
266eb7fbc25SPierre Schweitzer {
267*06042735SVincent Franchomme     ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
268eb7fbc25SPierre Schweitzer     const BYTE* ip = (const BYTE*)src;
269eb7fbc25SPierre Schweitzer     BYTE* op = (BYTE*)dst;
270eb7fbc25SPierre Schweitzer     BYTE* const oend = op + length;
271*06042735SVincent Franchomme 
272*06042735SVincent Franchomme     assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff <= -WILDCOPY_VECLEN));
273*06042735SVincent Franchomme 
274*06042735SVincent Franchomme     if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
275*06042735SVincent Franchomme         /* Handle short offset copies. */
276*06042735SVincent Franchomme         do {
277eb7fbc25SPierre Schweitzer             COPY8(op, ip)
278*06042735SVincent Franchomme         } while (op < oend);
279*06042735SVincent Franchomme     } else {
280*06042735SVincent Franchomme         assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
281*06042735SVincent Franchomme         /* Separate out the first COPY16() call because the copy length is
282*06042735SVincent Franchomme          * almost certain to be short, so the branches have different
283*06042735SVincent Franchomme          * probabilities. Since it is almost certain to be short, only do
284*06042735SVincent Franchomme          * one COPY16() in the first call. Then, do two calls per loop since
285*06042735SVincent Franchomme          * at that point it is more likely to have a high trip count.
286*06042735SVincent Franchomme          */
287*06042735SVincent Franchomme #ifndef __aarch64__
288*06042735SVincent Franchomme         do {
289*06042735SVincent Franchomme             COPY16(op, ip);
290*06042735SVincent Franchomme         }
291eb7fbc25SPierre Schweitzer         while (op < oend);
292*06042735SVincent Franchomme #else
293*06042735SVincent Franchomme         COPY16(op, ip);
294*06042735SVincent Franchomme         if (op >= oend) return;
295*06042735SVincent Franchomme         do {
296*06042735SVincent Franchomme             COPY16(op, ip);
297*06042735SVincent Franchomme             COPY16(op, ip);
298*06042735SVincent Franchomme         }
299*06042735SVincent Franchomme         while (op < oend);
300*06042735SVincent Franchomme #endif
301*06042735SVincent Franchomme     }
302eb7fbc25SPierre Schweitzer }
303eb7fbc25SPierre Schweitzer 
ZSTD_limitCopy(void * dst,size_t dstCapacity,const void * src,size_t srcSize)304*06042735SVincent Franchomme MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
305eb7fbc25SPierre Schweitzer {
306*06042735SVincent Franchomme     size_t const length = MIN(dstCapacity, srcSize);
307*06042735SVincent Franchomme     if (length > 0) {
308*06042735SVincent Franchomme         memcpy(dst, src, length);
309eb7fbc25SPierre Schweitzer     }
310*06042735SVincent Franchomme     return length;
311*06042735SVincent Franchomme }
312*06042735SVincent Franchomme 
313*06042735SVincent Franchomme /* define "workspace is too large" as this number of times larger than needed */
314*06042735SVincent Franchomme #define ZSTD_WORKSPACETOOLARGE_FACTOR 3
315*06042735SVincent Franchomme 
316*06042735SVincent Franchomme /* when workspace is continuously too large
317*06042735SVincent Franchomme  * during at least this number of times,
318*06042735SVincent Franchomme  * context's memory usage is considered wasteful,
319*06042735SVincent Franchomme  * because it's sized to handle a worst case scenario which rarely happens.
320*06042735SVincent Franchomme  * In which case, resize it down to free some memory */
321*06042735SVincent Franchomme #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
322eb7fbc25SPierre Schweitzer 
323eb7fbc25SPierre Schweitzer 
324eb7fbc25SPierre Schweitzer /*-*******************************************
325eb7fbc25SPierre Schweitzer *  Private declarations
326eb7fbc25SPierre Schweitzer *********************************************/
327eb7fbc25SPierre Schweitzer typedef struct seqDef_s {
328eb7fbc25SPierre Schweitzer     U32 offset;
329eb7fbc25SPierre Schweitzer     U16 litLength;
330eb7fbc25SPierre Schweitzer     U16 matchLength;
331eb7fbc25SPierre Schweitzer } seqDef;
332eb7fbc25SPierre Schweitzer 
333eb7fbc25SPierre Schweitzer typedef struct {
334eb7fbc25SPierre Schweitzer     seqDef* sequencesStart;
335eb7fbc25SPierre Schweitzer     seqDef* sequences;
336eb7fbc25SPierre Schweitzer     BYTE* litStart;
337eb7fbc25SPierre Schweitzer     BYTE* lit;
338eb7fbc25SPierre Schweitzer     BYTE* llCode;
339eb7fbc25SPierre Schweitzer     BYTE* mlCode;
340eb7fbc25SPierre Schweitzer     BYTE* ofCode;
341eb7fbc25SPierre Schweitzer     size_t maxNbSeq;
342eb7fbc25SPierre Schweitzer     size_t maxNbLit;
343eb7fbc25SPierre Schweitzer     U32   longLengthID;   /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
344eb7fbc25SPierre Schweitzer     U32   longLengthPos;
345eb7fbc25SPierre Schweitzer } seqStore_t;
346eb7fbc25SPierre Schweitzer 
347*06042735SVincent Franchomme typedef struct {
348*06042735SVincent Franchomme     U32 litLength;
349*06042735SVincent Franchomme     U32 matchLength;
350*06042735SVincent Franchomme } ZSTD_sequenceLength;
351*06042735SVincent Franchomme 
352*06042735SVincent Franchomme /**
353*06042735SVincent Franchomme  * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
354*06042735SVincent Franchomme  * indicated by longLengthPos and longLengthID, and adds MINMATCH back to matchLength.
355*06042735SVincent Franchomme  */
ZSTD_getSequenceLength(seqStore_t const * seqStore,seqDef const * seq)356*06042735SVincent Franchomme MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
357*06042735SVincent Franchomme {
358*06042735SVincent Franchomme     ZSTD_sequenceLength seqLen;
359*06042735SVincent Franchomme     seqLen.litLength = seq->litLength;
360*06042735SVincent Franchomme     seqLen.matchLength = seq->matchLength + MINMATCH;
361*06042735SVincent Franchomme     if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
362*06042735SVincent Franchomme         if (seqStore->longLengthID == 1) {
363*06042735SVincent Franchomme             seqLen.litLength += 0xFFFF;
364*06042735SVincent Franchomme         }
365*06042735SVincent Franchomme         if (seqStore->longLengthID == 2) {
366*06042735SVincent Franchomme             seqLen.matchLength += 0xFFFF;
367*06042735SVincent Franchomme         }
368*06042735SVincent Franchomme     }
369*06042735SVincent Franchomme     return seqLen;
370*06042735SVincent Franchomme }
371*06042735SVincent Franchomme 
372*06042735SVincent Franchomme /**
373*06042735SVincent Franchomme  * Contains the compressed frame size and an upper-bound for the decompressed frame size.
374*06042735SVincent Franchomme  * Note: before using `compressedSize`, check for errors using ZSTD_isError().
375*06042735SVincent Franchomme  *       similarly, before using `decompressedBound`, check for errors using:
376*06042735SVincent Franchomme  *          `decompressedBound != ZSTD_CONTENTSIZE_ERROR`
377*06042735SVincent Franchomme  */
378*06042735SVincent Franchomme typedef struct {
379*06042735SVincent Franchomme     size_t compressedSize;
380*06042735SVincent Franchomme     unsigned long long decompressedBound;
381*06042735SVincent Franchomme } ZSTD_frameSizeInfo;   /* decompress & legacy */
382*06042735SVincent Franchomme 
383eb7fbc25SPierre Schweitzer const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);   /* compress & dictBuilder */
384eb7fbc25SPierre Schweitzer void ZSTD_seqToCodes(const seqStore_t* seqStorePtr);   /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
385eb7fbc25SPierre Schweitzer 
386eb7fbc25SPierre Schweitzer /* custom memory allocation functions */
387eb7fbc25SPierre Schweitzer void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
388eb7fbc25SPierre Schweitzer void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
389eb7fbc25SPierre Schweitzer void ZSTD_free(void* ptr, ZSTD_customMem customMem);
390eb7fbc25SPierre Schweitzer 
391eb7fbc25SPierre Schweitzer 
ZSTD_highbit32(U32 val)392eb7fbc25SPierre Schweitzer MEM_STATIC U32 ZSTD_highbit32(U32 val)   /* compress, dictBuilder, decodeCorpus */
393eb7fbc25SPierre Schweitzer {
394eb7fbc25SPierre Schweitzer     assert(val != 0);
395eb7fbc25SPierre Schweitzer     {
396eb7fbc25SPierre Schweitzer #   if defined(_MSC_VER)   /* Visual */
397eb7fbc25SPierre Schweitzer         unsigned long r=0;
398*06042735SVincent Franchomme         return _BitScanReverse(&r, val) ? (unsigned)r : 0;
399eb7fbc25SPierre Schweitzer #   elif defined(__GNUC__) && (__GNUC__ >= 3)   /* GCC Intrinsic */
400*06042735SVincent Franchomme         return __builtin_clz (val) ^ 31;
401*06042735SVincent Franchomme #   elif defined(__ICCARM__)    /* IAR Intrinsic */
402*06042735SVincent Franchomme         return 31 - __CLZ(val);
403eb7fbc25SPierre Schweitzer #   else   /* Software version */
404eb7fbc25SPierre Schweitzer         static const U32 DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
405eb7fbc25SPierre Schweitzer         U32 v = val;
406eb7fbc25SPierre Schweitzer         v |= v >> 1;
407eb7fbc25SPierre Schweitzer         v |= v >> 2;
408eb7fbc25SPierre Schweitzer         v |= v >> 4;
409eb7fbc25SPierre Schweitzer         v |= v >> 8;
410eb7fbc25SPierre Schweitzer         v |= v >> 16;
411eb7fbc25SPierre Schweitzer         return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];
412eb7fbc25SPierre Schweitzer #   endif
413eb7fbc25SPierre Schweitzer     }
414eb7fbc25SPierre Schweitzer }
415eb7fbc25SPierre Schweitzer 
416eb7fbc25SPierre Schweitzer 
417eb7fbc25SPierre Schweitzer /* ZSTD_invalidateRepCodes() :
418eb7fbc25SPierre Schweitzer  * ensures next compression will not use repcodes from previous block.
419eb7fbc25SPierre Schweitzer  * Note : only works with regular variant;
420eb7fbc25SPierre Schweitzer  *        do not use with extDict variant ! */
421eb7fbc25SPierre Schweitzer void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);   /* zstdmt, adaptive_compression (shouldn't get this definition from here) */
422eb7fbc25SPierre Schweitzer 
423eb7fbc25SPierre Schweitzer 
424eb7fbc25SPierre Schweitzer typedef struct {
425eb7fbc25SPierre Schweitzer     blockType_e blockType;
426eb7fbc25SPierre Schweitzer     U32 lastBlock;
427eb7fbc25SPierre Schweitzer     U32 origSize;
428*06042735SVincent Franchomme } blockProperties_t;   /* declared here for decompress and fullbench */
429eb7fbc25SPierre Schweitzer 
430eb7fbc25SPierre Schweitzer /*! ZSTD_getcBlockSize() :
431eb7fbc25SPierre Schweitzer  *  Provides the size of compressed block from block header `src` */
432eb7fbc25SPierre Schweitzer /* Used by: decompress, fullbench (does not get its definition from here) */
433eb7fbc25SPierre Schweitzer size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
434eb7fbc25SPierre Schweitzer                           blockProperties_t* bpPtr);
435eb7fbc25SPierre Schweitzer 
436*06042735SVincent Franchomme /*! ZSTD_decodeSeqHeaders() :
437*06042735SVincent Franchomme  *  decode sequence header from src */
438*06042735SVincent Franchomme /* Used by: decompress, fullbench (does not get its definition from here) */
439*06042735SVincent Franchomme size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
440*06042735SVincent Franchomme                        const void* src, size_t srcSize);
441*06042735SVincent Franchomme 
442*06042735SVincent Franchomme 
443eb7fbc25SPierre Schweitzer #if defined (__cplusplus)
444eb7fbc25SPierre Schweitzer }
445eb7fbc25SPierre Schweitzer #endif
446eb7fbc25SPierre Schweitzer 
447eb7fbc25SPierre Schweitzer #endif   /* ZSTD_CCOMMON_H_MODULE */
448