1 | /* |
2 | * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. |
3 | * All rights reserved. |
4 | * |
5 | * This source code is licensed under both the BSD-style license (found in the |
6 | * LICENSE file in the root directory of this source tree) and the GPLv2 (found |
7 | * in the COPYING file in the root directory of this source tree). |
8 | * You may select, at your option, one of the above-listed licenses. |
9 | */ |
10 | |
11 | #ifndef ZSTD_LEGACY_H |
12 | #define ZSTD_LEGACY_H |
13 | |
14 | #if defined (__cplusplus) |
15 | extern "C" { |
16 | #endif |
17 | |
18 | /* ************************************* |
19 | * Includes |
20 | ***************************************/ |
21 | #include "mem.h" /* MEM_STATIC */ |
22 | #include "error_private.h" /* ERROR */ |
23 | #include "zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer */ |
24 | |
25 | #if !defined (ZSTD_LEGACY_SUPPORT) || (ZSTD_LEGACY_SUPPORT == 0) |
26 | # undef ZSTD_LEGACY_SUPPORT |
27 | # define ZSTD_LEGACY_SUPPORT 8 |
28 | #endif |
29 | |
30 | #if (ZSTD_LEGACY_SUPPORT <= 1) |
31 | # include "zstd_v01.h" |
32 | #endif |
33 | #if (ZSTD_LEGACY_SUPPORT <= 2) |
34 | # include "zstd_v02.h" |
35 | #endif |
36 | #if (ZSTD_LEGACY_SUPPORT <= 3) |
37 | # include "zstd_v03.h" |
38 | #endif |
39 | #if (ZSTD_LEGACY_SUPPORT <= 4) |
40 | # include "zstd_v04.h" |
41 | #endif |
42 | #if (ZSTD_LEGACY_SUPPORT <= 5) |
43 | # include "zstd_v05.h" |
44 | #endif |
45 | #if (ZSTD_LEGACY_SUPPORT <= 6) |
46 | # include "zstd_v06.h" |
47 | #endif |
48 | #if (ZSTD_LEGACY_SUPPORT <= 7) |
49 | # include "zstd_v07.h" |
50 | #endif |
51 | |
52 | /** ZSTD_isLegacy() : |
53 | @return : > 0 if supported by legacy decoder. 0 otherwise. |
54 | return value is the version. |
55 | */ |
56 | MEM_STATIC unsigned ZSTD_isLegacy(const void* src, size_t srcSize) |
57 | { |
58 | U32 magicNumberLE; |
59 | if (srcSize<4) return 0; |
60 | magicNumberLE = MEM_readLE32(src); |
61 | switch(magicNumberLE) |
62 | { |
63 | #if (ZSTD_LEGACY_SUPPORT <= 1) |
64 | case ZSTDv01_magicNumberLE:return 1; |
65 | #endif |
66 | #if (ZSTD_LEGACY_SUPPORT <= 2) |
67 | case ZSTDv02_magicNumber : return 2; |
68 | #endif |
69 | #if (ZSTD_LEGACY_SUPPORT <= 3) |
70 | case ZSTDv03_magicNumber : return 3; |
71 | #endif |
72 | #if (ZSTD_LEGACY_SUPPORT <= 4) |
73 | case ZSTDv04_magicNumber : return 4; |
74 | #endif |
75 | #if (ZSTD_LEGACY_SUPPORT <= 5) |
76 | case ZSTDv05_MAGICNUMBER : return 5; |
77 | #endif |
78 | #if (ZSTD_LEGACY_SUPPORT <= 6) |
79 | case ZSTDv06_MAGICNUMBER : return 6; |
80 | #endif |
81 | #if (ZSTD_LEGACY_SUPPORT <= 7) |
82 | case ZSTDv07_MAGICNUMBER : return 7; |
83 | #endif |
84 | default : return 0; |
85 | } |
86 | } |
87 | |
88 | |
89 | MEM_STATIC unsigned long long ZSTD_getDecompressedSize_legacy(const void* src, size_t srcSize) |
90 | { |
91 | U32 const version = ZSTD_isLegacy(src, srcSize); |
92 | if (version < 5) return 0; /* no decompressed size in frame header, or not a legacy format */ |
93 | #if (ZSTD_LEGACY_SUPPORT <= 5) |
94 | if (version==5) { |
95 | ZSTDv05_parameters fParams; |
96 | size_t const frResult = ZSTDv05_getFrameParams(&fParams, src, srcSize); |
97 | if (frResult != 0) return 0; |
98 | return fParams.srcSize; |
99 | } |
100 | #endif |
101 | #if (ZSTD_LEGACY_SUPPORT <= 6) |
102 | if (version==6) { |
103 | ZSTDv06_frameParams fParams; |
104 | size_t const frResult = ZSTDv06_getFrameParams(&fParams, src, srcSize); |
105 | if (frResult != 0) return 0; |
106 | return fParams.frameContentSize; |
107 | } |
108 | #endif |
109 | #if (ZSTD_LEGACY_SUPPORT <= 7) |
110 | if (version==7) { |
111 | ZSTDv07_frameParams fParams; |
112 | size_t const frResult = ZSTDv07_getFrameParams(&fParams, src, srcSize); |
113 | if (frResult != 0) return 0; |
114 | return fParams.frameContentSize; |
115 | } |
116 | #endif |
117 | return 0; /* should not be possible */ |
118 | } |
119 | |
120 | |
121 | MEM_STATIC size_t ZSTD_decompressLegacy( |
122 | void* dst, size_t dstCapacity, |
123 | const void* src, size_t compressedSize, |
124 | const void* dict,size_t dictSize) |
125 | { |
126 | U32 const version = ZSTD_isLegacy(src, compressedSize); |
127 | (void)dst; (void)dstCapacity; (void)dict; (void)dictSize; /* unused when ZSTD_LEGACY_SUPPORT >= 8 */ |
128 | switch(version) |
129 | { |
130 | #if (ZSTD_LEGACY_SUPPORT <= 1) |
131 | case 1 : |
132 | return ZSTDv01_decompress(dst, dstCapacity, src, compressedSize); |
133 | #endif |
134 | #if (ZSTD_LEGACY_SUPPORT <= 2) |
135 | case 2 : |
136 | return ZSTDv02_decompress(dst, dstCapacity, src, compressedSize); |
137 | #endif |
138 | #if (ZSTD_LEGACY_SUPPORT <= 3) |
139 | case 3 : |
140 | return ZSTDv03_decompress(dst, dstCapacity, src, compressedSize); |
141 | #endif |
142 | #if (ZSTD_LEGACY_SUPPORT <= 4) |
143 | case 4 : |
144 | return ZSTDv04_decompress(dst, dstCapacity, src, compressedSize); |
145 | #endif |
146 | #if (ZSTD_LEGACY_SUPPORT <= 5) |
147 | case 5 : |
148 | { size_t result; |
149 | ZSTDv05_DCtx* const zd = ZSTDv05_createDCtx(); |
150 | if (zd==NULL) return ERROR(memory_allocation); |
151 | result = ZSTDv05_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize); |
152 | ZSTDv05_freeDCtx(zd); |
153 | return result; |
154 | } |
155 | #endif |
156 | #if (ZSTD_LEGACY_SUPPORT <= 6) |
157 | case 6 : |
158 | { size_t result; |
159 | ZSTDv06_DCtx* const zd = ZSTDv06_createDCtx(); |
160 | if (zd==NULL) return ERROR(memory_allocation); |
161 | result = ZSTDv06_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize); |
162 | ZSTDv06_freeDCtx(zd); |
163 | return result; |
164 | } |
165 | #endif |
166 | #if (ZSTD_LEGACY_SUPPORT <= 7) |
167 | case 7 : |
168 | { size_t result; |
169 | ZSTDv07_DCtx* const zd = ZSTDv07_createDCtx(); |
170 | if (zd==NULL) return ERROR(memory_allocation); |
171 | result = ZSTDv07_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize); |
172 | ZSTDv07_freeDCtx(zd); |
173 | return result; |
174 | } |
175 | #endif |
176 | default : |
177 | return ERROR(prefix_unknown); |
178 | } |
179 | } |
180 | |
181 | MEM_STATIC size_t ZSTD_findFrameCompressedSizeLegacy(const void *src, |
182 | size_t compressedSize) |
183 | { |
184 | U32 const version = ZSTD_isLegacy(src, compressedSize); |
185 | switch(version) |
186 | { |
187 | #if (ZSTD_LEGACY_SUPPORT <= 1) |
188 | case 1 : |
189 | return ZSTDv01_findFrameCompressedSize(src, compressedSize); |
190 | #endif |
191 | #if (ZSTD_LEGACY_SUPPORT <= 2) |
192 | case 2 : |
193 | return ZSTDv02_findFrameCompressedSize(src, compressedSize); |
194 | #endif |
195 | #if (ZSTD_LEGACY_SUPPORT <= 3) |
196 | case 3 : |
197 | return ZSTDv03_findFrameCompressedSize(src, compressedSize); |
198 | #endif |
199 | #if (ZSTD_LEGACY_SUPPORT <= 4) |
200 | case 4 : |
201 | return ZSTDv04_findFrameCompressedSize(src, compressedSize); |
202 | #endif |
203 | #if (ZSTD_LEGACY_SUPPORT <= 5) |
204 | case 5 : |
205 | return ZSTDv05_findFrameCompressedSize(src, compressedSize); |
206 | #endif |
207 | #if (ZSTD_LEGACY_SUPPORT <= 6) |
208 | case 6 : |
209 | return ZSTDv06_findFrameCompressedSize(src, compressedSize); |
210 | #endif |
211 | #if (ZSTD_LEGACY_SUPPORT <= 7) |
212 | case 7 : |
213 | return ZSTDv07_findFrameCompressedSize(src, compressedSize); |
214 | #endif |
215 | default : |
216 | return ERROR(prefix_unknown); |
217 | } |
218 | } |
219 | |
220 | MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version) |
221 | { |
222 | switch(version) |
223 | { |
224 | default : |
225 | case 1 : |
226 | case 2 : |
227 | case 3 : |
228 | (void)legacyContext; |
229 | return ERROR(version_unsupported); |
230 | #if (ZSTD_LEGACY_SUPPORT <= 4) |
231 | case 4 : return ZBUFFv04_freeDCtx((ZBUFFv04_DCtx*)legacyContext); |
232 | #endif |
233 | #if (ZSTD_LEGACY_SUPPORT <= 5) |
234 | case 5 : return ZBUFFv05_freeDCtx((ZBUFFv05_DCtx*)legacyContext); |
235 | #endif |
236 | #if (ZSTD_LEGACY_SUPPORT <= 6) |
237 | case 6 : return ZBUFFv06_freeDCtx((ZBUFFv06_DCtx*)legacyContext); |
238 | #endif |
239 | #if (ZSTD_LEGACY_SUPPORT <= 7) |
240 | case 7 : return ZBUFFv07_freeDCtx((ZBUFFv07_DCtx*)legacyContext); |
241 | #endif |
242 | } |
243 | } |
244 | |
245 | |
246 | MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion, |
247 | const void* dict, size_t dictSize) |
248 | { |
249 | DEBUGLOG(5, "ZSTD_initLegacyStream for v0.%u" , newVersion); |
250 | if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion); |
251 | switch(newVersion) |
252 | { |
253 | default : |
254 | case 1 : |
255 | case 2 : |
256 | case 3 : |
257 | (void)dict; (void)dictSize; |
258 | return 0; |
259 | #if (ZSTD_LEGACY_SUPPORT <= 4) |
260 | case 4 : |
261 | { |
262 | ZBUFFv04_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv04_createDCtx() : (ZBUFFv04_DCtx*)*legacyContext; |
263 | if (dctx==NULL) return ERROR(memory_allocation); |
264 | ZBUFFv04_decompressInit(dctx); |
265 | ZBUFFv04_decompressWithDictionary(dctx, dict, dictSize); |
266 | *legacyContext = dctx; |
267 | return 0; |
268 | } |
269 | #endif |
270 | #if (ZSTD_LEGACY_SUPPORT <= 5) |
271 | case 5 : |
272 | { |
273 | ZBUFFv05_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv05_createDCtx() : (ZBUFFv05_DCtx*)*legacyContext; |
274 | if (dctx==NULL) return ERROR(memory_allocation); |
275 | ZBUFFv05_decompressInitDictionary(dctx, dict, dictSize); |
276 | *legacyContext = dctx; |
277 | return 0; |
278 | } |
279 | #endif |
280 | #if (ZSTD_LEGACY_SUPPORT <= 6) |
281 | case 6 : |
282 | { |
283 | ZBUFFv06_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv06_createDCtx() : (ZBUFFv06_DCtx*)*legacyContext; |
284 | if (dctx==NULL) return ERROR(memory_allocation); |
285 | ZBUFFv06_decompressInitDictionary(dctx, dict, dictSize); |
286 | *legacyContext = dctx; |
287 | return 0; |
288 | } |
289 | #endif |
290 | #if (ZSTD_LEGACY_SUPPORT <= 7) |
291 | case 7 : |
292 | { |
293 | ZBUFFv07_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv07_createDCtx() : (ZBUFFv07_DCtx*)*legacyContext; |
294 | if (dctx==NULL) return ERROR(memory_allocation); |
295 | ZBUFFv07_decompressInitDictionary(dctx, dict, dictSize); |
296 | *legacyContext = dctx; |
297 | return 0; |
298 | } |
299 | #endif |
300 | } |
301 | } |
302 | |
303 | |
304 | |
305 | MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version, |
306 | ZSTD_outBuffer* output, ZSTD_inBuffer* input) |
307 | { |
308 | DEBUGLOG(5, "ZSTD_decompressLegacyStream for v0.%u" , version); |
309 | switch(version) |
310 | { |
311 | default : |
312 | case 1 : |
313 | case 2 : |
314 | case 3 : |
315 | (void)legacyContext; (void)output; (void)input; |
316 | return ERROR(version_unsupported); |
317 | #if (ZSTD_LEGACY_SUPPORT <= 4) |
318 | case 4 : |
319 | { |
320 | ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) legacyContext; |
321 | const void* src = (const char*)input->src + input->pos; |
322 | size_t readSize = input->size - input->pos; |
323 | void* dst = (char*)output->dst + output->pos; |
324 | size_t decodedSize = output->size - output->pos; |
325 | size_t const hintSize = ZBUFFv04_decompressContinue(dctx, dst, &decodedSize, src, &readSize); |
326 | output->pos += decodedSize; |
327 | input->pos += readSize; |
328 | return hintSize; |
329 | } |
330 | #endif |
331 | #if (ZSTD_LEGACY_SUPPORT <= 5) |
332 | case 5 : |
333 | { |
334 | ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) legacyContext; |
335 | const void* src = (const char*)input->src + input->pos; |
336 | size_t readSize = input->size - input->pos; |
337 | void* dst = (char*)output->dst + output->pos; |
338 | size_t decodedSize = output->size - output->pos; |
339 | size_t const hintSize = ZBUFFv05_decompressContinue(dctx, dst, &decodedSize, src, &readSize); |
340 | output->pos += decodedSize; |
341 | input->pos += readSize; |
342 | return hintSize; |
343 | } |
344 | #endif |
345 | #if (ZSTD_LEGACY_SUPPORT <= 6) |
346 | case 6 : |
347 | { |
348 | ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) legacyContext; |
349 | const void* src = (const char*)input->src + input->pos; |
350 | size_t readSize = input->size - input->pos; |
351 | void* dst = (char*)output->dst + output->pos; |
352 | size_t decodedSize = output->size - output->pos; |
353 | size_t const hintSize = ZBUFFv06_decompressContinue(dctx, dst, &decodedSize, src, &readSize); |
354 | output->pos += decodedSize; |
355 | input->pos += readSize; |
356 | return hintSize; |
357 | } |
358 | #endif |
359 | #if (ZSTD_LEGACY_SUPPORT <= 7) |
360 | case 7 : |
361 | { |
362 | ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) legacyContext; |
363 | const void* src = (const char*)input->src + input->pos; |
364 | size_t readSize = input->size - input->pos; |
365 | void* dst = (char*)output->dst + output->pos; |
366 | size_t decodedSize = output->size - output->pos; |
367 | size_t const hintSize = ZBUFFv07_decompressContinue(dctx, dst, &decodedSize, src, &readSize); |
368 | output->pos += decodedSize; |
369 | input->pos += readSize; |
370 | return hintSize; |
371 | } |
372 | #endif |
373 | } |
374 | } |
375 | |
376 | |
377 | #if defined (__cplusplus) |
378 | } |
379 | #endif |
380 | |
381 | #endif /* ZSTD_LEGACY_H */ |
382 | |