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