2016-08-30 17:04:33 +00:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*/
|
2015-10-30 10:21:50 +00:00
|
|
|
|
|
|
|
#ifndef ZSTD_LEGACY_H
|
|
|
|
#define ZSTD_LEGACY_H
|
|
|
|
|
|
|
|
#if defined (__cplusplus)
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* *************************************
|
|
|
|
* Includes
|
|
|
|
***************************************/
|
2016-01-21 14:50:11 +00:00
|
|
|
#include "mem.h" /* MEM_STATIC */
|
|
|
|
#include "error_private.h" /* ERROR */
|
2016-08-28 14:43:34 +00:00
|
|
|
#include "zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer */
|
2015-10-30 10:21:50 +00:00
|
|
|
#include "zstd_v01.h"
|
|
|
|
#include "zstd_v02.h"
|
2015-11-26 15:02:04 +00:00
|
|
|
#include "zstd_v03.h"
|
2016-02-03 00:09:46 +00:00
|
|
|
#include "zstd_v04.h"
|
2016-04-09 07:42:27 +00:00
|
|
|
#include "zstd_v05.h"
|
2016-06-09 15:59:18 +00:00
|
|
|
#include "zstd_v06.h"
|
2016-07-25 15:49:08 +00:00
|
|
|
#include "zstd_v07.h"
|
2015-10-30 10:21:50 +00:00
|
|
|
|
2016-05-06 14:43:23 +00:00
|
|
|
|
|
|
|
/** ZSTD_isLegacy() :
|
|
|
|
@return : > 0 if supported by legacy decoder. 0 otherwise.
|
|
|
|
return value is the version.
|
|
|
|
*/
|
2016-07-07 12:40:13 +00:00
|
|
|
MEM_STATIC unsigned ZSTD_isLegacy(const void* src, size_t srcSize)
|
2015-10-30 10:21:50 +00:00
|
|
|
{
|
2016-07-07 12:40:13 +00:00
|
|
|
U32 magicNumberLE;
|
|
|
|
if (srcSize<4) return 0;
|
|
|
|
magicNumberLE = MEM_readLE32(src);
|
2016-06-09 15:59:18 +00:00
|
|
|
switch(magicNumberLE)
|
|
|
|
{
|
|
|
|
case ZSTDv01_magicNumberLE:return 1;
|
|
|
|
case ZSTDv02_magicNumber : return 2;
|
|
|
|
case ZSTDv03_magicNumber : return 3;
|
|
|
|
case ZSTDv04_magicNumber : return 4;
|
|
|
|
case ZSTDv05_MAGICNUMBER : return 5;
|
|
|
|
case ZSTDv06_MAGICNUMBER : return 6;
|
2016-07-25 15:49:08 +00:00
|
|
|
case ZSTDv07_MAGICNUMBER : return 7;
|
2016-06-09 15:59:18 +00:00
|
|
|
default : return 0;
|
|
|
|
}
|
2015-10-30 10:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-07-07 11:14:21 +00:00
|
|
|
MEM_STATIC unsigned long long ZSTD_getDecompressedSize_legacy(const void* src, size_t srcSize)
|
|
|
|
{
|
2016-08-28 14:43:34 +00:00
|
|
|
U32 const version = ZSTD_isLegacy(src, srcSize);
|
|
|
|
if (version < 5) return 0; /* no decompressed size in frame header, or not a legacy format */
|
|
|
|
if (version==5) {
|
|
|
|
ZSTDv05_parameters fParams;
|
|
|
|
size_t const frResult = ZSTDv05_getFrameParams(&fParams, src, srcSize);
|
|
|
|
if (frResult != 0) return 0;
|
|
|
|
return fParams.srcSize;
|
|
|
|
}
|
|
|
|
if (version==6) {
|
|
|
|
ZSTDv06_frameParams fParams;
|
|
|
|
size_t const frResult = ZSTDv06_getFrameParams(&fParams, src, srcSize);
|
|
|
|
if (frResult != 0) return 0;
|
|
|
|
return fParams.frameContentSize;
|
|
|
|
}
|
|
|
|
if (version==7) {
|
|
|
|
ZSTDv07_frameParams fParams;
|
|
|
|
size_t const frResult = ZSTDv07_getFrameParams(&fParams, src, srcSize);
|
|
|
|
if (frResult != 0) return 0;
|
|
|
|
return fParams.frameContentSize;
|
2016-07-07 11:14:21 +00:00
|
|
|
}
|
2016-08-28 14:43:34 +00:00
|
|
|
return 0; /* should not be possible */
|
2016-07-07 11:14:21 +00:00
|
|
|
}
|
|
|
|
|
2016-08-28 14:43:34 +00:00
|
|
|
|
2015-10-30 10:21:50 +00:00
|
|
|
MEM_STATIC size_t ZSTD_decompressLegacy(
|
2016-04-09 07:42:27 +00:00
|
|
|
void* dst, size_t dstCapacity,
|
2015-10-30 10:21:50 +00:00
|
|
|
const void* src, size_t compressedSize,
|
2016-07-07 12:40:13 +00:00
|
|
|
const void* dict,size_t dictSize)
|
2015-10-30 10:21:50 +00:00
|
|
|
{
|
2016-07-07 12:40:13 +00:00
|
|
|
U32 const version = ZSTD_isLegacy(src, compressedSize);
|
|
|
|
switch(version)
|
2016-06-09 15:59:18 +00:00
|
|
|
{
|
2016-07-07 12:40:13 +00:00
|
|
|
case 1 :
|
2016-06-09 15:59:18 +00:00
|
|
|
return ZSTDv01_decompress(dst, dstCapacity, src, compressedSize);
|
2016-07-07 12:40:13 +00:00
|
|
|
case 2 :
|
2016-06-09 15:59:18 +00:00
|
|
|
return ZSTDv02_decompress(dst, dstCapacity, src, compressedSize);
|
2016-07-07 12:40:13 +00:00
|
|
|
case 3 :
|
2016-06-09 15:59:18 +00:00
|
|
|
return ZSTDv03_decompress(dst, dstCapacity, src, compressedSize);
|
2016-07-07 12:40:13 +00:00
|
|
|
case 4 :
|
2016-06-09 15:59:18 +00:00
|
|
|
return ZSTDv04_decompress(dst, dstCapacity, src, compressedSize);
|
2016-07-07 12:40:13 +00:00
|
|
|
case 5 :
|
2016-06-10 22:23:43 +00:00
|
|
|
{ size_t result;
|
|
|
|
ZSTDv05_DCtx* const zd = ZSTDv05_createDCtx();
|
2016-06-09 15:59:18 +00:00
|
|
|
if (zd==NULL) return ERROR(memory_allocation);
|
|
|
|
result = ZSTDv05_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
|
|
|
|
ZSTDv05_freeDCtx(zd);
|
|
|
|
return result;
|
|
|
|
}
|
2016-07-07 12:40:13 +00:00
|
|
|
case 6 :
|
2016-06-10 22:23:43 +00:00
|
|
|
{ size_t result;
|
|
|
|
ZSTDv06_DCtx* const zd = ZSTDv06_createDCtx();
|
2016-06-09 15:59:18 +00:00
|
|
|
if (zd==NULL) return ERROR(memory_allocation);
|
|
|
|
result = ZSTDv06_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
|
|
|
|
ZSTDv06_freeDCtx(zd);
|
|
|
|
return result;
|
|
|
|
}
|
2016-07-25 15:49:08 +00:00
|
|
|
case 7 :
|
|
|
|
{ size_t result;
|
|
|
|
ZSTDv07_DCtx* const zd = ZSTDv07_createDCtx();
|
|
|
|
if (zd==NULL) return ERROR(memory_allocation);
|
|
|
|
result = ZSTDv07_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
|
|
|
|
ZSTDv07_freeDCtx(zd);
|
|
|
|
return result;
|
|
|
|
}
|
2016-06-09 15:59:18 +00:00
|
|
|
default :
|
|
|
|
return ERROR(prefix_unknown);
|
|
|
|
}
|
2015-10-30 10:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-28 14:43:34 +00:00
|
|
|
MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version)
|
|
|
|
{
|
|
|
|
switch(version)
|
|
|
|
{
|
|
|
|
default :
|
|
|
|
case 1 :
|
|
|
|
case 2 :
|
|
|
|
case 3 :
|
|
|
|
return ERROR(version_unsupported);
|
|
|
|
case 4 : return ZBUFFv04_freeDCtx((ZBUFFv04_DCtx*)legacyContext);
|
|
|
|
case 5 : return ZBUFFv05_freeDCtx((ZBUFFv05_DCtx*)legacyContext);
|
|
|
|
case 6 : return ZBUFFv06_freeDCtx((ZBUFFv06_DCtx*)legacyContext);
|
|
|
|
case 7 : return ZBUFFv07_freeDCtx((ZBUFFv07_DCtx*)legacyContext);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-28 15:19:47 +00:00
|
|
|
MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion,
|
|
|
|
const void* dict, size_t dictSize)
|
2016-08-28 14:43:34 +00:00
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion);
|
|
|
|
switch(newVersion)
|
2016-08-28 14:43:34 +00:00
|
|
|
{
|
|
|
|
default :
|
|
|
|
case 1 :
|
|
|
|
case 2 :
|
|
|
|
case 3 :
|
2016-08-28 15:19:47 +00:00
|
|
|
return 0;
|
2016-08-28 14:43:34 +00:00
|
|
|
case 4 :
|
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
ZBUFFv04_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv04_createDCtx() : (ZBUFFv04_DCtx*)*legacyContext;
|
|
|
|
if (dctx==NULL) return ERROR(memory_allocation);
|
2016-08-28 14:43:34 +00:00
|
|
|
ZBUFFv04_decompressInit(dctx);
|
|
|
|
ZBUFFv04_decompressWithDictionary(dctx, dict, dictSize);
|
2016-08-28 15:19:47 +00:00
|
|
|
*legacyContext = dctx;
|
|
|
|
return 0;
|
2016-08-28 14:43:34 +00:00
|
|
|
}
|
|
|
|
case 5 :
|
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
ZBUFFv05_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv05_createDCtx() : (ZBUFFv05_DCtx*)*legacyContext;
|
|
|
|
if (dctx==NULL) return ERROR(memory_allocation);
|
2016-08-28 14:43:34 +00:00
|
|
|
ZBUFFv05_decompressInitDictionary(dctx, dict, dictSize);
|
2016-08-28 15:19:47 +00:00
|
|
|
*legacyContext = dctx;
|
|
|
|
return 0;
|
2016-08-28 14:43:34 +00:00
|
|
|
}
|
|
|
|
case 6 :
|
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
ZBUFFv06_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv06_createDCtx() : (ZBUFFv06_DCtx*)*legacyContext;
|
|
|
|
if (dctx==NULL) return ERROR(memory_allocation);
|
2016-08-28 14:43:34 +00:00
|
|
|
ZBUFFv06_decompressInitDictionary(dctx, dict, dictSize);
|
2016-08-28 15:19:47 +00:00
|
|
|
*legacyContext = dctx;
|
|
|
|
return 0;
|
2016-08-28 14:43:34 +00:00
|
|
|
}
|
|
|
|
case 7 :
|
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
ZBUFFv07_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv07_createDCtx() : (ZBUFFv07_DCtx*)*legacyContext;
|
|
|
|
if (dctx==NULL) return ERROR(memory_allocation);
|
2016-08-28 14:43:34 +00:00
|
|
|
ZBUFFv07_decompressInitDictionary(dctx, dict, dictSize);
|
2016-08-28 15:19:47 +00:00
|
|
|
*legacyContext = dctx;
|
|
|
|
return 0;
|
2016-08-28 14:43:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-28 15:19:47 +00:00
|
|
|
MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version,
|
|
|
|
ZSTD_outBuffer* output, ZSTD_inBuffer* input)
|
2016-08-28 14:43:34 +00:00
|
|
|
{
|
|
|
|
switch(version)
|
|
|
|
{
|
|
|
|
default :
|
|
|
|
case 1 :
|
|
|
|
case 2 :
|
|
|
|
case 3 :
|
|
|
|
return ERROR(version_unsupported);
|
|
|
|
case 4 :
|
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) legacyContext;
|
2016-08-28 14:43:34 +00:00
|
|
|
const void* src = (const char*)input->src + input->pos;
|
|
|
|
size_t readSize = input->size - input->pos;
|
|
|
|
void* dst = (char*)output->dst + output->pos;
|
|
|
|
size_t decodedSize = output->size - output->pos;
|
|
|
|
size_t const hintSize = ZBUFFv04_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
|
|
|
|
output->pos += decodedSize;
|
|
|
|
input->pos += readSize;
|
|
|
|
return hintSize;
|
|
|
|
}
|
|
|
|
case 5 :
|
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) legacyContext;
|
2016-08-28 14:43:34 +00:00
|
|
|
const void* src = (const char*)input->src + input->pos;
|
|
|
|
size_t readSize = input->size - input->pos;
|
|
|
|
void* dst = (char*)output->dst + output->pos;
|
|
|
|
size_t decodedSize = output->size - output->pos;
|
|
|
|
size_t const hintSize = ZBUFFv05_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
|
|
|
|
output->pos += decodedSize;
|
|
|
|
input->pos += readSize;
|
|
|
|
return hintSize;
|
|
|
|
}
|
|
|
|
case 6 :
|
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) legacyContext;
|
2016-08-28 14:43:34 +00:00
|
|
|
const void* src = (const char*)input->src + input->pos;
|
|
|
|
size_t readSize = input->size - input->pos;
|
|
|
|
void* dst = (char*)output->dst + output->pos;
|
|
|
|
size_t decodedSize = output->size - output->pos;
|
|
|
|
size_t const hintSize = ZBUFFv06_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
|
|
|
|
output->pos += decodedSize;
|
|
|
|
input->pos += readSize;
|
|
|
|
return hintSize;
|
|
|
|
}
|
|
|
|
case 7 :
|
|
|
|
{
|
2016-08-28 15:19:47 +00:00
|
|
|
ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) legacyContext;
|
2016-08-28 14:43:34 +00:00
|
|
|
const void* src = (const char*)input->src + input->pos;
|
|
|
|
size_t readSize = input->size - input->pos;
|
|
|
|
void* dst = (char*)output->dst + output->pos;
|
|
|
|
size_t decodedSize = output->size - output->pos;
|
|
|
|
size_t const hintSize = ZBUFFv07_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
|
|
|
|
output->pos += decodedSize;
|
|
|
|
input->pos += readSize;
|
|
|
|
return hintSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-30 10:21:50 +00:00
|
|
|
|
|
|
|
#if defined (__cplusplus)
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* ZSTD_LEGACY_H */
|