1 /* Lzma2DecMt.c -- LZMA2 Decoder Multi-thread
2 2019-02-02 : Igor Pavlov : Public domain */
6 // #define SHOW_DEBUG_INFO
12 #ifdef SHOW_DEBUG_INFO
18 #define PRF_STR(s) PRF(printf("\n" s "\n"))
19 #define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d))
20 #define PRF_STR_INT_2(s, d1, d2) PRF(printf("\n" s " %d %d\n", (unsigned)d1, (unsigned)d2))
27 #include "Lzma2DecMt.h"
34 #define LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT (1 << 28)
36 void Lzma2DecMtProps_Init(CLzma2DecMtProps
*p
)
38 p
->inBufSize_ST
= 1 << 20;
39 p
->outStep_ST
= 1 << 20;
43 p
->inBufSize_MT
= 1 << 18;
44 p
->outBlockMax
= LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT
;
45 p
->inBlockMax
= p
->outBlockMax
+ p
->outBlockMax
/ 16;
53 /* ---------- CLzma2DecMtThread ---------- */
64 EMtDecParseState state
;
65 ELzma2ParseStatus parseStatus
;
74 CAlignOffsetAlloc alloc
;
82 /* ---------- CLzma2DecMt ---------- */
89 CAlignOffsetAlloc alignOffsetAlloc
;
90 CLzma2DecMtProps props
;
93 ISeqInStream
*inStream
;
94 ISeqOutStream
*outStream
;
95 ICompressProgress
*progress
;
98 BoolInt outSize_Defined
;
103 BoolInt readWasFinished
;
115 UInt64 outProcessed_Parse
;
116 BoolInt mtc_WasConstructed
;
118 CLzma2DecMtThread coders
[MTDEC__THREADS_MAX
];
125 CLzma2DecMtHandle
Lzma2DecMt_Create(ISzAllocPtr alloc
, ISzAllocPtr allocMid
)
127 CLzma2DecMt
*p
= (CLzma2DecMt
*)ISzAlloc_Alloc(alloc
, sizeof(CLzma2DecMt
));
132 p
->allocMid
= allocMid
;
134 AlignOffsetAlloc_CreateVTable(&p
->alignOffsetAlloc
);
135 p
->alignOffsetAlloc
.numAlignBits
= 7;
136 p
->alignOffsetAlloc
.offset
= 0;
137 p
->alignOffsetAlloc
.baseAlloc
= alloc
;
141 p
->dec_created
= False
;
143 // Lzma2DecMtProps_Init(&p->props);
146 p
->mtc_WasConstructed
= False
;
149 for (i
= 0; i
< MTDEC__THREADS_MAX
; i
++)
151 CLzma2DecMtThread
*t
= &p
->coders
[i
];
152 t
->dec_created
= False
;
165 static void Lzma2DecMt_FreeOutBufs(CLzma2DecMt
*p
)
168 for (i
= 0; i
< MTDEC__THREADS_MAX
; i
++)
170 CLzma2DecMtThread
*t
= &p
->coders
[i
];
173 ISzAlloc_Free(p
->allocMid
, t
->outBuf
);
183 static void Lzma2DecMt_FreeSt(CLzma2DecMt
*p
)
187 Lzma2Dec_Free(&p
->dec
, &p
->alignOffsetAlloc
.vt
);
188 p
->dec_created
= False
;
192 ISzAlloc_Free(p
->allocMid
, p
->inBuf
);
199 void Lzma2DecMt_Destroy(CLzma2DecMtHandle pp
)
201 CLzma2DecMt
*p
= (CLzma2DecMt
*)pp
;
203 Lzma2DecMt_FreeSt(p
);
207 if (p
->mtc_WasConstructed
)
209 MtDec_Destruct(&p
->mtc
);
210 p
->mtc_WasConstructed
= False
;
214 for (i
= 0; i
< MTDEC__THREADS_MAX
; i
++)
216 CLzma2DecMtThread
*t
= &p
->coders
[i
];
219 // we don't need to free dict here
220 Lzma2Dec_FreeProbs(&t
->dec
, &t
->alloc
.vt
); // p->alloc !!!
221 t
->dec_created
= False
;
225 Lzma2DecMt_FreeOutBufs(p
);
229 ISzAlloc_Free(p
->alignOffsetAlloc
.baseAlloc
, pp
);
236 static void Lzma2DecMt_MtCallback_Parse(void *obj
, unsigned coderIndex
, CMtDecCallbackInfo
*cc
)
238 CLzma2DecMt
*me
= (CLzma2DecMt
*)obj
;
239 CLzma2DecMtThread
*t
= &me
->coders
[coderIndex
];
241 PRF_STR_INT_2("Parse", coderIndex
, cc
->srcSize
);
243 cc
->state
= MTDEC_PARSE_CONTINUE
;
249 Lzma2Dec_Construct(&t
->dec
);
250 t
->dec_created
= True
;
251 AlignOffsetAlloc_CreateVTable(&t
->alloc
);
253 /* (1 << 12) is expected size of one way in data cache.
254 We optimize alignment for cache line size of 128 bytes and smaller */
255 const unsigned kNumAlignBits
= 12;
256 const unsigned kNumCacheLineBits
= 7; /* <= kNumAlignBits */
257 t
->alloc
.numAlignBits
= kNumAlignBits
;
258 t
->alloc
.offset
= ((UInt32
)coderIndex
* ((1 << 11) + (1 << 8) + (1 << 6))) & ((1 << kNumAlignBits
) - (1 << kNumCacheLineBits
));
259 t
->alloc
.baseAlloc
= me
->alignOffsetAlloc
.baseAlloc
;
262 Lzma2Dec_Init(&t
->dec
);
266 // t->blockWasFinished = False;
267 // t->finishedWithMark = False;
268 t
->parseStatus
= (ELzma2ParseStatus
)LZMA_STATUS_NOT_SPECIFIED
;
269 t
->state
= MTDEC_PARSE_CONTINUE
;
275 // (cc->srcSize == 0) is allowed
279 ELzma2ParseStatus status
;
281 UInt32 unpackRem
= 0;
283 int checkFinishBlock
= True
;
284 size_t limit
= me
->props
.outBlockMax
;
285 if (me
->outSize_Defined
)
287 UInt64 rem
= me
->outSize
- me
->outProcessed_Parse
;
292 checkFinishBlock
= False
;
296 // checkFinishBlock = False, if we want to decode partial data
297 // that must be finished at position <= outBlockMax.
300 const SizeT srcOrig
= cc
->srcSize
;
301 SizeT srcSize_Point
= 0;
302 SizeT dicPos_Point
= 0;
309 SizeT srcCur
= srcOrig
- cc
->srcSize
;
311 status
= Lzma2Dec_Parse(&t
->dec
,
312 limit
- t
->dec
.decoder
.dicPos
,
313 cc
->src
+ cc
->srcSize
, &srcCur
,
316 cc
->srcSize
+= srcCur
;
318 if (status
== LZMA2_PARSE_STATUS_NEW_CHUNK
)
320 if (t
->dec
.unpackSize
> me
->props
.outBlockMax
- t
->dec
.decoder
.dicPos
)
328 if (status
== LZMA2_PARSE_STATUS_NEW_BLOCK
)
330 if (t
->dec
.decoder
.dicPos
== 0)
332 // we decode small blocks in one thread
333 if (t
->dec
.decoder
.dicPos
>= (1 << 14))
335 dicPos_Point
= t
->dec
.decoder
.dicPos
;
336 srcSize_Point
= cc
->srcSize
;
340 if ((int)status
== LZMA_STATUS_NOT_FINISHED
&& checkFinishBlock
341 // && limit == t->dec.decoder.dicPos
342 // && limit == me->props.outBlockMax
349 unpackRem
= Lzma2Dec_GetUnpackExtra(&t
->dec
);
353 if (dicPos_Point
!= 0
354 && (int)status
!= LZMA2_PARSE_STATUS_NEW_BLOCK
355 && (int)status
!= LZMA_STATUS_FINISHED_WITH_MARK
356 && (int)status
!= LZMA_STATUS_NOT_SPECIFIED
)
358 // we revert to latest newBlock state
359 status
= LZMA2_PARSE_STATUS_NEW_BLOCK
;
361 t
->dec
.decoder
.dicPos
= dicPos_Point
;
362 cc
->srcSize
= srcSize_Point
;
367 t
->inPreSize
+= cc
->srcSize
;
368 t
->parseStatus
= status
;
371 cc
->state
= MTDEC_PARSE_OVERFLOW
;
374 size_t dicPos
= t
->dec
.decoder
.dicPos
;
376 if ((int)status
!= LZMA_STATUS_NEEDS_MORE_INPUT
)
378 if (status
== LZMA2_PARSE_STATUS_NEW_BLOCK
)
380 cc
->state
= MTDEC_PARSE_NEW
;
381 cc
->srcSize
--; // we don't need control byte of next block
386 cc
->state
= MTDEC_PARSE_END
;
387 if ((int)status
!= LZMA_STATUS_FINISHED_WITH_MARK
)
389 // (status == LZMA_STATUS_NOT_SPECIFIED)
390 // (status == LZMA_STATUS_NOT_FINISHED)
393 /* we also reserve space for max possible number of output bytes of current LZMA chunk */
394 SizeT rem
= limit
- dicPos
;
402 me
->outProcessed_Parse
+= dicPos
;
406 t
->outPreSize
= (size_t)dicPos
;
409 t
->state
= cc
->state
;
415 static SRes
Lzma2DecMt_MtCallback_PreCode(void *pp
, unsigned coderIndex
)
417 CLzma2DecMt
*me
= (CLzma2DecMt
*)pp
;
418 CLzma2DecMtThread
*t
= &me
->coders
[coderIndex
];
419 Byte
*dest
= t
->outBuf
;
421 if (t
->inPreSize
== 0)
423 t
->codeRes
= SZ_ERROR_DATA
;
427 if (!dest
|| t
->outBufSize
< t
->outPreSize
)
431 ISzAlloc_Free(me
->allocMid
, dest
);
436 dest
= (Byte
*)ISzAlloc_Alloc(me
->allocMid
, t
->outPreSize
443 t
->outBufSize
= t
->outPreSize
;
446 t
->dec
.decoder
.dic
= dest
;
447 t
->dec
.decoder
.dicBufSize
= t
->outPreSize
;
451 return Lzma2Dec_AllocateProbs(&t
->dec
, me
->prop
, &t
->alloc
.vt
); // alloc.vt
455 static SRes
Lzma2DecMt_MtCallback_Code(void *pp
, unsigned coderIndex
,
456 const Byte
*src
, size_t srcSize
, int srcFinished
,
457 // int finished, int blockFinished,
458 UInt64
*inCodePos
, UInt64
*outCodePos
, int *stop
)
460 CLzma2DecMt
*me
= (CLzma2DecMt
*)pp
;
461 CLzma2DecMtThread
*t
= &me
->coders
[coderIndex
];
463 UNUSED_VAR(srcFinished
)
465 PRF_STR_INT_2("Code", coderIndex
, srcSize
);
467 *inCodePos
= t
->inCodeSize
;
473 Lzma2Dec_Init(&t
->dec
);
479 size_t srcProcessed
= srcSize
;
480 BoolInt blockWasFinished
=
481 ((int)t
->parseStatus
== LZMA_STATUS_FINISHED_WITH_MARK
482 || t
->parseStatus
== LZMA2_PARSE_STATUS_NEW_BLOCK
);
484 SRes res
= Lzma2Dec_DecodeToDic(&t
->dec
,
487 blockWasFinished
? LZMA_FINISH_END
: LZMA_FINISH_ANY
,
492 t
->inCodeSize
+= srcProcessed
;
493 *inCodePos
= t
->inCodeSize
;
494 t
->outCodeSize
= t
->dec
.decoder
.dicPos
;
495 *outCodePos
= t
->dec
.decoder
.dicPos
;
500 if (srcProcessed
== srcSize
)
503 if (blockWasFinished
)
505 if (srcSize
!= srcProcessed
)
506 return SZ_ERROR_FAIL
;
508 if (t
->inPreSize
== t
->inCodeSize
)
510 if (t
->outPreSize
!= t
->outCodeSize
)
511 return SZ_ERROR_FAIL
;
517 if (t
->outPreSize
== t
->outCodeSize
)
526 #define LZMA2DECMT_STREAM_WRITE_STEP (1 << 24)
528 static SRes
Lzma2DecMt_MtCallback_Write(void *pp
, unsigned coderIndex
,
529 BoolInt needWriteToStream
,
530 const Byte
*src
, size_t srcSize
,
531 BoolInt
*needContinue
, BoolInt
*canRecode
)
533 CLzma2DecMt
*me
= (CLzma2DecMt
*)pp
;
534 const CLzma2DecMtThread
*t
= &me
->coders
[coderIndex
];
535 size_t size
= t
->outCodeSize
;
536 const Byte
*data
= t
->outBuf
;
537 BoolInt needContinue2
= True
;
539 PRF_STR_INT_2("Write", coderIndex
, srcSize
);
541 *needContinue
= False
;
547 // t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK
548 t
->state
== MTDEC_PARSE_OVERFLOW
549 || t
->state
== MTDEC_PARSE_END
)
550 needContinue2
= False
;
553 if (!needWriteToStream
)
556 me
->mtc
.inProcessed
+= t
->inCodeSize
;
558 if (t
->codeRes
== SZ_OK
)
559 if ((int)t
->parseStatus
== LZMA_STATUS_FINISHED_WITH_MARK
560 || t
->parseStatus
== LZMA2_PARSE_STATUS_NEW_BLOCK
)
561 if (t
->outPreSize
!= t
->outCodeSize
562 || t
->inPreSize
!= t
->inCodeSize
)
563 return SZ_ERROR_FAIL
;
573 if (cur
> LZMA2DECMT_STREAM_WRITE_STEP
)
574 cur
= LZMA2DECMT_STREAM_WRITE_STEP
;
576 written
= ISeqOutStream_Write(me
->outStream
, data
, cur
);
578 me
->outProcessed
+= written
;
579 // me->mtc.writtenTotal += written;
581 return SZ_ERROR_WRITE
;
586 *needContinue
= needContinue2
;
589 RINOK(MtProgress_ProgressAdd(&me
->mtc
.mtProgress
, 0, 0));
593 return SZ_ERROR_FAIL
;
595 if (size > me->outBufSize)
596 return SZ_ERROR_OUTPUT_EOF;
597 memcpy(me->outBuf, data, size);
598 me->outBufSize -= size;
600 *needContinue = needContinue2;
608 static SRes
Lzma2Dec_Prepare_ST(CLzma2DecMt
*p
)
612 Lzma2Dec_Construct(&p
->dec
);
613 p
->dec_created
= True
;
616 RINOK(Lzma2Dec_Allocate(&p
->dec
, p
->prop
, &p
->alignOffsetAlloc
.vt
));
618 if (!p
->inBuf
|| p
->inBufSize
!= p
->props
.inBufSize_ST
)
620 ISzAlloc_Free(p
->allocMid
, p
->inBuf
);
622 p
->inBuf
= (Byte
*)ISzAlloc_Alloc(p
->allocMid
, p
->props
.inBufSize_ST
);
625 p
->inBufSize
= p
->props
.inBufSize_ST
;
628 Lzma2Dec_Init(&p
->dec
);
634 static SRes
Lzma2Dec_Decode_ST(CLzma2DecMt
*p
643 UInt64 inPrev
, outPrev
;
650 Lzma2DecMt_FreeOutBufs(p
);
651 tMode
= MtDec_PrepareRead(&p
->mtc
);
655 RINOK(Lzma2Dec_Prepare_ST(p
));
659 inPrev
= p
->inProcessed
;
660 outPrev
= p
->outProcessed
;
665 wrPos
= dec
->decoder
.dicPos
;
671 ELzmaFinishMode finishMode
;
685 inData
= MtDec_Read(&p
->mtc
, &inLim
);
694 if (!p
->readWasFinished
)
697 inLim
= p
->inBufSize
;
699 p
->readRes
= ISeqInStream_Read(p
->inStream
, (void *)inData
, &inLim
);
700 // p->readProcessed += inLim;
701 // inLim -= 5; p->readWasFinished = True; // for test
702 if (inLim
== 0 || p
->readRes
!= SZ_OK
)
703 p
->readWasFinished
= True
;
707 dicPos
= dec
->decoder
.dicPos
;
709 SizeT next
= dec
->decoder
.dicBufSize
;
710 if (next
- wrPos
> p
->props
.outStep_ST
)
711 next
= wrPos
+ p
->props
.outStep_ST
;
712 size
= next
- dicPos
;
715 finishMode
= LZMA_FINISH_ANY
;
716 if (p
->outSize_Defined
)
718 const UInt64 rem
= p
->outSize
- p
->outProcessed
;
723 finishMode
= LZMA_FINISH_END
;
727 inProcessed
= inLim
- inPos
;
729 res
= Lzma2Dec_DecodeToDic(dec
, dicPos
+ size
, inData
+ inPos
, &inProcessed
, finishMode
, &status
);
731 inPos
+= inProcessed
;
732 p
->inProcessed
+= inProcessed
;
733 outProcessed
= dec
->decoder
.dicPos
- dicPos
;
734 p
->outProcessed
+= outProcessed
;
736 outFinished
= (p
->outSize_Defined
&& p
->outSize
<= p
->outProcessed
);
738 needStop
= (res
!= SZ_OK
739 || (inProcessed
== 0 && outProcessed
== 0)
740 || status
== LZMA_STATUS_FINISHED_WITH_MARK
741 || (!p
->finishMode
&& outFinished
));
743 if (needStop
|| outProcessed
>= size
)
747 size_t writeSize
= dec
->decoder
.dicPos
- wrPos
;
748 size_t written
= ISeqOutStream_Write(p
->outStream
, dec
->decoder
.dic
+ wrPos
, writeSize
);
749 res2
= (written
== writeSize
) ? SZ_OK
: SZ_ERROR_WRITE
;
752 if (dec
->decoder
.dicPos
== dec
->decoder
.dicBufSize
)
753 dec
->decoder
.dicPos
= 0;
754 wrPos
= dec
->decoder
.dicPos
;
763 if (status
== LZMA_STATUS_FINISHED_WITH_MARK
)
767 if (p
->outSize_Defined
&& p
->outSize
!= p
->outProcessed
)
768 return SZ_ERROR_DATA
;
773 if (!p
->finishMode
&& outFinished
)
776 if (status
== LZMA_STATUS_NEEDS_MORE_INPUT
)
777 return SZ_ERROR_INPUT_EOF
;
779 return SZ_ERROR_DATA
;
785 UInt64 inDelta
= p
->inProcessed
- inPrev
;
786 UInt64 outDelta
= p
->outProcessed
- outPrev
;
787 if (inDelta
>= (1 << 22) || outDelta
>= (1 << 22))
789 RINOK(ICompressProgress_Progress(p
->progress
, p
->inProcessed
, p
->outProcessed
));
790 inPrev
= p
->inProcessed
;
791 outPrev
= p
->outProcessed
;
799 SRes
Lzma2DecMt_Decode(CLzma2DecMtHandle pp
,
801 const CLzma2DecMtProps
*props
,
802 ISeqOutStream
*outStream
, const UInt64
*outDataSize
, int finishMode
,
803 // Byte *outBuf, size_t *outBufSize,
804 ISeqInStream
*inStream
,
805 // const Byte *inData, size_t inDataSize,
807 // UInt64 *outProcessed,
809 ICompressProgress
*progress
)
811 CLzma2DecMt
*p
= (CLzma2DecMt
*)pp
;
819 return SZ_ERROR_UNSUPPORTED
;
824 p
->inStream
= inStream
;
825 p
->outStream
= outStream
;
826 p
->progress
= progress
;
829 p
->outSize_Defined
= False
;
832 p
->outSize_Defined
= True
;
833 p
->outSize
= *outDataSize
;
835 p
->finishMode
= finishMode
;
840 p
->readWasFinished
= False
;
849 // p->mtc.parseRes = SZ_OK;
851 // p->mtc.numFilledThreads = 0;
852 // p->mtc.crossStart = 0;
853 // p->mtc.crossEnd = 0;
854 // p->mtc.allocError_for_Read_BlockIndex = 0;
855 // p->mtc.isAllocError = False;
857 if (p
->props
.numThreads
> 1)
861 Lzma2DecMt_FreeSt(p
);
863 p
->outProcessed_Parse
= 0;
865 if (!p
->mtc_WasConstructed
)
867 p
->mtc_WasConstructed
= True
;
868 MtDec_Construct(&p
->mtc
);
871 p
->mtc
.progress
= progress
;
872 p
->mtc
.inStream
= inStream
;
875 // p->outBufSize = 0;
879 // p->outBuf = outBuf;
880 // p->outBufSize = *outBufSize;
882 return SZ_ERROR_PARAM;
886 // p->mtc.inBlockMax = p->props.inBlockMax;
887 p
->mtc
.alloc
= &p
->alignOffsetAlloc
.vt
;
888 // p->alignOffsetAlloc.baseAlloc;
889 // p->mtc.inData = inData;
890 // p->mtc.inDataSize = inDataSize;
891 p
->mtc
.mtCallback
= &vt
;
892 p
->mtc
.mtCallbackObject
= p
;
894 p
->mtc
.inBufSize
= p
->props
.inBufSize_MT
;
896 p
->mtc
.numThreadsMax
= p
->props
.numThreads
;
900 vt
.Parse
= Lzma2DecMt_MtCallback_Parse
;
901 vt
.PreCode
= Lzma2DecMt_MtCallback_PreCode
;
902 vt
.Code
= Lzma2DecMt_MtCallback_Code
;
903 vt
.Write
= Lzma2DecMt_MtCallback_Write
;
906 BoolInt needContinue
= False
;
908 SRes res
= MtDec_Code(&p
->mtc
);
912 *outBufSize = p->outBuf - outBuf;
915 *inProcessed
= p
->mtc
.inProcessed
;
917 needContinue
= False
;
921 if (p
->mtc
.mtProgress
.res
!= SZ_OK
)
922 res
= p
->mtc
.mtProgress
.res
;
924 needContinue
= p
->mtc
.needContinue
;
930 return p
->mtc
.readRes
;
935 p
->readRes
= p
->mtc
.readRes
;
936 p
->readWasFinished
= p
->mtc
.readWasFinished
;
937 p
->inProcessed
= p
->mtc
.inProcessed
;
939 PRF_STR("----- decoding ST -----");
949 SRes res
= Lzma2Dec_Decode_ST(p
955 *inProcessed
= p
->inProcessed
;
957 // res = SZ_OK; // for test
958 if (res
== SZ_OK
&& p
->readRes
!= SZ_OK
)
963 if (res == SZ_OK && tMode && p->mtc.parseRes != SZ_OK)
964 res = p->mtc.parseRes;
973 /* ---------- Read from CLzma2DecMtHandle Interface ---------- */
975 SRes
Lzma2DecMt_Init(CLzma2DecMtHandle pp
,
977 const CLzma2DecMtProps
*props
,
978 const UInt64
*outDataSize
, int finishMode
,
979 ISeqInStream
*inStream
)
981 CLzma2DecMt
*p
= (CLzma2DecMt
*)pp
;
984 return SZ_ERROR_UNSUPPORTED
;
989 p
->inStream
= inStream
;
992 p
->outSize_Defined
= False
;
995 p
->outSize_Defined
= True
;
996 p
->outSize
= *outDataSize
;
998 p
->finishMode
= finishMode
;
1000 p
->outProcessed
= 0;
1006 return Lzma2Dec_Prepare_ST(p
);
1010 SRes
Lzma2DecMt_Read(CLzma2DecMtHandle pp
,
1011 Byte
*data
, size_t *outSize
,
1012 UInt64
*inStreamProcessed
)
1014 CLzma2DecMt
*p
= (CLzma2DecMt
*)pp
;
1015 ELzmaFinishMode finishMode
;
1017 size_t size
= *outSize
;
1020 *inStreamProcessed
= 0;
1022 finishMode
= LZMA_FINISH_ANY
;
1023 if (p
->outSize_Defined
)
1025 const UInt64 rem
= p
->outSize
- p
->outProcessed
;
1030 finishMode
= LZMA_FINISH_END
;
1043 if (p
->inPos
== p
->inLim
&& readRes
== SZ_OK
)
1046 p
->inLim
= p
->props
.inBufSize_ST
;
1047 readRes
= ISeqInStream_Read(p
->inStream
, p
->inBuf
, &p
->inLim
);
1050 inCur
= p
->inLim
- p
->inPos
;
1053 res
= Lzma2Dec_DecodeToBuf(&p
->dec
, data
, &outCur
,
1054 p
->inBuf
+ p
->inPos
, &inCur
, finishMode
, &status
);
1057 p
->inProcessed
+= inCur
;
1058 *inStreamProcessed
+= inCur
;
1059 p
->outProcessed
+= outCur
;
1068 if (status == LZMA_STATUS_FINISHED_WITH_MARK)
1071 if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT)
1073 if (p->finishMode && p->outSize_Defined && p->outProcessed >= p->outSize)
1074 return SZ_ERROR_DATA;
1079 if (inCur
== 0 && outCur
== 0)