diff options
Diffstat (limited to 'src/libs/7zip/unix/C/XzDec.c')
-rw-r--r-- | src/libs/7zip/unix/C/XzDec.c | 108 |
1 files changed, 71 insertions, 37 deletions
diff --git a/src/libs/7zip/unix/C/XzDec.c b/src/libs/7zip/unix/C/XzDec.c index 40f1a2a45..6eef587d3 100644 --- a/src/libs/7zip/unix/C/XzDec.c +++ b/src/libs/7zip/unix/C/XzDec.c @@ -1,5 +1,7 @@ /* XzDec.c -- Xz Decode -2010-04-16 : Igor Pavlov : Public domain */ +2014-12-30 : Igor Pavlov : Public domain */ + +#include "Precomp.h" /* #define XZ_DUMP */ @@ -18,7 +20,8 @@ #include "Lzma2Dec.h" #ifdef USE_SUBBLOCK -#include "SbDec.h" +#include "Bcj3Dec.c" +#include "SbDec.c" #endif #include "Xz.h" @@ -72,7 +75,6 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a { CBraState *p = ((CBraState *)pp); alloc = alloc; - p->encodeMode = 0; p->ip = 0; if (p->methodId == XZ_ID_Delta) { @@ -195,7 +197,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, return SZ_OK; } -SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc) +SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc) { CBraState *decoder; if (id != XZ_ID_Delta && @@ -207,10 +209,11 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc) id != XZ_ID_SPARC) return SZ_ERROR_UNSUPPORTED; p->p = 0; - decoder = alloc->Alloc(alloc, sizeof(CBraState)); + decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState)); if (decoder == 0) return SZ_ERROR_MEM; decoder->methodId = (UInt32)id; + decoder->encodeMode = encodeMode; p->p = decoder; p->Free = BraState_Free; p->SetProps = BraState_SetProps; @@ -225,8 +228,8 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc) static void SbState_Free(void *pp, ISzAlloc *alloc) { - CSubblockDec *p = (CSubblockDec *)pp; - SubblockDec_Free(p, alloc); + CSbDec *p = (CSbDec *)pp; + SbDec_Free(p); alloc->Free(alloc, pp); } @@ -240,24 +243,32 @@ static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAl static void SbState_Init(void *pp) { - SubblockDec_Init((CSubblockDec *)pp); + SbDec_Init((CSbDec *)pp); } static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished) { - ECoderStatus status; - SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status); + CSbDec *p = (CSbDec *)pp; + SRes res; srcWasFinished = srcWasFinished; - *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK); + p->dest = dest; + p->destLen = *destLen; + p->src = src; + p->srcLen = *srcLen; + p->finish = finishMode; /* change it */ + res = SbDec_Decode((CSbDec *)pp); + *destLen -= p->destLen; + *srcLen -= p->srcLen; + *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */ return res; } SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) { - CSubblockDec *decoder; + CSbDec *decoder; p->p = 0; - decoder = alloc->Alloc(alloc, sizeof(CSubblockDec)); + decoder = alloc->Alloc(alloc, sizeof(CSbDec)); if (decoder == 0) return SZ_ERROR_MEM; p->p = decoder; @@ -265,7 +276,8 @@ SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) p->SetProps = SbState_SetProps; p->Init = SbState_Init; p->Code = SbState_Code; - SubblockDec_Construct(decoder); + SbDec_Construct(decoder); + SbDec_SetAlloc(decoder, alloc); return SZ_OK; } #endif @@ -295,7 +307,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr { ELzmaStatus status; /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ - SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status); + SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status); srcWasFinished = srcWasFinished; *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK); return res; @@ -303,7 +315,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc) { - CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec)); + CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec)); p->p = decoder; if (decoder == 0) return SZ_ERROR_MEM; @@ -337,7 +349,10 @@ void MixCoder_Free(CMixCoder *p) } p->numCoders = 0; if (p->buf) + { p->alloc->Free(p->alloc, p->buf); + p->buf = 0; /* 9.31: the BUG was fixed */ + } } void MixCoder_Init(CMixCoder *p) @@ -369,7 +384,7 @@ SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId) } if (coderIndex == 0) return SZ_ERROR_UNSUPPORTED; - return BraState_SetFromMethod(sc, methodId, p->alloc); + return BraState_SetFromMethod(sc, methodId, 0, p->alloc); } SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, @@ -385,7 +400,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, if (p->buf == 0) { - p->buf = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); + p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); if (p->buf == 0) return SZ_ERROR_MEM; } @@ -411,7 +426,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, const Byte *srcCur; int srcFinishedCur; int encodingWasFinished; - + if (i == 0) { srcCur = src; @@ -424,7 +439,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, srcLenCur = p->size[i - 1] - p->pos[i - 1]; srcFinishedCur = p->finished[i - 1]; } - + if (i == p->numCoders - 1) { destCur = dest; @@ -437,7 +452,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, destCur = p->buf + (CODER_BUF_SIZE * i); destLenCur = CODER_BUF_SIZE; } - + res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished); if (!encodingWasFinished) @@ -464,7 +479,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen, p->pos[i] = 0; p->finished[i] = encodingWasFinished; } - + if (res != SZ_OK) return res; @@ -587,13 +602,20 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block) return SZ_OK; } -SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc) +void XzUnpacker_Init(CXzUnpacker *p) { - MixCoder_Construct(&p->decoder, alloc); p->state = XZ_STATE_STREAM_HEADER; p->pos = 0; - p->numStreams = 0; - return SZ_OK; + p->numStartedStreams = 0; + p->numFinishedStreams = 0; + p->numTotalBlocks = 0; + p->padSize = 0; +} + +void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc) +{ + MixCoder_Construct(&p->decoder, alloc); + XzUnpacker_Init(p); } void XzUnpacker_Free(CXzUnpacker *p) @@ -602,7 +624,7 @@ void XzUnpacker_Free(CXzUnpacker *p) } SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status) + const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status) { SizeT destLenOrig = *destLen; SizeT srcLenOrig = *srcLen; @@ -623,20 +645,20 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, *status = CODER_STATUS_NOT_FINISHED; return SZ_OK; } - + res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status); XzCheck_Update(&p->check, dest, destLen2); - + (*srcLen) += srcLen2; src += srcLen2; p->packSize += srcLen2; - + (*destLen) += destLen2; dest += destLen2; p->unpackSize += destLen2; - + RINOK(res); - + if (*status == CODER_STATUS_FINISHED_WITH_MARK) { Byte temp[32]; @@ -645,14 +667,14 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, Sha256_Update(&p->sha, temp, num); p->indexSize += num; p->numBlocks++; - + p->state = XZ_STATE_BLOCK_FOOTER; p->pos = 0; p->alignPos = 0; } else if (srcLen2 == 0 && destLen2 == 0) return SZ_OK; - + continue; } @@ -662,7 +684,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, return SZ_OK; } - switch(p->state) + switch (p->state) { case XZ_STATE_STREAM_HEADER: { @@ -676,6 +698,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, else { RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)); + p->numStartedStreams++; p->state = XZ_STATE_BLOCK_HEADER; Sha256_Init(&p->sha); p->indexSize = 0; @@ -716,6 +739,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, else { RINOK(XzBlock_Parse(&p->block, p->buf)); + p->numTotalBlocks++; p->state = XZ_STATE_BLOCK; p->packSize = 0; p->unpackSize = 0; @@ -833,7 +857,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, if (p->pos == XZ_STREAM_FOOTER_SIZE) { p->state = XZ_STATE_STREAM_PADDING; - p->numStreams++; + p->numFinishedStreams++; p->padSize = 0; if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf)) return SZ_ERROR_CRC; @@ -858,7 +882,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, } break; } - + case XZ_STATE_BLOCK: break; /* to disable GCC warning */ } } @@ -873,3 +897,13 @@ Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p) { return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0); } + +UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p) +{ + UInt64 num = 0; + if (p->state == XZ_STATE_STREAM_PADDING) + num += p->padSize; + else if (p->state == XZ_STATE_STREAM_HEADER) + num += p->padSize + p->pos; + return num; +} |