// File: sisong[P]ApkDiffPatch/HDiffPatch/libHDiffPatch/HPatch/patch.c
// Function: patch_single_stream_diff
hpatch_BOOL patch_single_stream_diff(const hpatch_TStreamOutput*  out_newData,
                                     const hpatch_TStreamInput*   oldData,
                                     const hpatch_TStreamInput*   uncompressedDiffData,
                                     hpatch_StreamPos_t           diffData_pos,
                                     hpatch_StreamPos_t           diffData_posEnd,
                                     hpatch_StreamPos_t coverCount,hpatch_size_t stepMemSize,
                                     unsigned char* temp_cache,unsigned char* temp_cache_end,
                                     sspatch_coversListener_t* coversListener){
    unsigned char*      step_cache=temp_cache;
    hpatch_size_t       cache_size;
    TStreamCacheClip    inClip;
    _TOutStreamCache     outCache;
    sspatch_covers_t    covers;
    assert(diffData_posEnd<=uncompressedDiffData->streamSize);
    sspatch_covers_init(&covers);
    if (coversListener) assert(coversListener->onStepCovers);
    {//cache
        if ((size_t)(temp_cache_end-temp_cache)<stepMemSize+hpatch_kStreamCacheSize*_kCacheSgCount) return _hpatch_FALSE;
        temp_cache+=stepMemSize;
        cache_size=(temp_cache_end-temp_cache)/_kCacheSgCount;
        _TStreamCacheClip_init(&inClip,uncompressedDiffData,diffData_pos,diffData_posEnd,
                               temp_cache,cache_size);
        temp_cache+=cache_size;
        _TOutStreamCache_init(&outCache,out_newData,temp_cache+cache_size,cache_size);
    }
    while (coverCount) {//step loop
        rle0_decoder_t       rle0_decoder;
        {//read step info
            unsigned char*      covers_cacheEnd;
            unsigned char*      bufRle_cache_end;
            {
                hpatch_StreamPos_t  bufCover_size;
                hpatch_StreamPos_t  bufRle_size;
                _clip_unpackUIntTo(&bufCover_size,&inClip);
                _clip_unpackUIntTo(&bufRle_size,&inClip);
                #ifdef __RUN_MEM_SAFE_CHECK
                    if ((bufCover_size>stepMemSize)|(bufRle_size>stepMemSize)|
                        (bufCover_size+bufRle_size>stepMemSize)) return _hpatch_FALSE;
                #endif
                covers_cacheEnd=step_cache+(size_t)bufCover_size;
                bufRle_cache_end=covers_cacheEnd+(size_t)bufRle_size;
            }
            if (coversListener&&coversListener->onStepCoversReset)
                coversListener->onStepCoversReset(coversListener,coverCount);
            if (!_TStreamCacheClip_readDataTo(&inClip,step_cache,bufRle_cache_end))
                return _hpatch_FALSE;
            if (coversListener)
                coversListener->onStepCovers(coversListener,step_cache,covers_cacheEnd);
            sspatch_covers_setCoversCache(&covers,step_cache,covers_cacheEnd);
            _rle0_decoder_init(&rle0_decoder,covers_cacheEnd,bufRle_cache_end);
        }
        while (sspatch_covers_isHaveNextCover(&covers)) {//cover loop
            if (!sspatch_covers_nextCover(&covers)) 
                return _hpatch_FALSE;
            if (covers.cover.newPos>covers.lastNewEnd){
                if (!_TOutStreamCache_copyFromClip(&outCache,&inClip,covers.cover.newPos-covers.lastNewEnd))
                    return _hpatch_FALSE;
            }
            
            --coverCount;
            if (covers.cover.length){
                #ifdef __RUN_MEM_SAFE_CHECK
                    if ((covers.cover.oldPos>oldData->streamSize)|
                        (covers.cover.length>(hpatch_StreamPos_t)(oldData->streamSize-covers.cover.oldPos))) return _hpatch_FALSE;
                #endif
                if (!_patch_add_old_with_rle0(&outCache,&rle0_decoder,oldData,covers.cover.oldPos,covers.cover.length,
                                              temp_cache,cache_size)) return _hpatch_FALSE;
            }else{
                #ifdef __RUN_MEM_SAFE_CHECK
                    if (coverCount!=0) return _hpatch_FALSE;
                #endif
            }
        }
    }
    
    if (!_TOutStreamCache_flush(&outCache))
        return _hpatch_FALSE;
    if (_TStreamCacheClip_isFinish(&inClip)&_TOutStreamCache_isFinish(&outCache)&(coverCount==0))
        return hpatch_TRUE;
    else
        return _hpatch_FALSE;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movq 0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x8(%rcx), %rax
ja 0x8997b
jmp 0x8999a
leaq 0x2b5b3(%rip), %rdi     # 0xb4f35
leaq 0x2b051(%rip), %rsi     # 0xb49da
movl $0x8a3, %edx            # imm = 0x8A3
leaq 0x2b5d2(%rip), %rcx     # 0xb4f67
callq 0x4270
leaq -0xd8(%rbp), %rdi
callq 0x8a1f0
cmpq $0x0, 0x28(%rbp)
je 0x899db
movq 0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x899ba
jmp 0x899d9
leaq 0x2b6ac(%rip), %rdi     # 0xb506d
leaq 0x2b012(%rip), %rsi     # 0xb49da
movl $0x8a5, %edx            # imm = 0x8A5
leaq 0x2b593(%rip), %rcx     # 0xb4f67
callq 0x4270
jmp 0x899db
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rcx
subq %rcx, %rax
movq 0x10(%rbp), %rcx
addq $0x3000, %rcx           # imm = 0x3000
cmpq %rcx, %rax
jae 0x89a02
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
movq 0x10(%rbp), %rax
addq 0x18(%rbp), %rax
movq %rax, 0x18(%rbp)
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rcx
subq %rcx, %rax
movl $0x3, %ecx
cqto
idivq %rcx
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq 0x18(%rbp), %r8
movq -0x48(%rbp), %r9
leaq -0x78(%rbp), %rdi
callq 0x871e0
movq -0x48(%rbp), %rax
addq 0x18(%rbp), %rax
movq %rax, 0x18(%rbp)
movq -0x10(%rbp), %rsi
movq 0x18(%rbp), %rdx
addq -0x48(%rbp), %rdx
movq -0x48(%rbp), %rcx
leaq -0xa0(%rbp), %rdi
callq 0x8a220
cmpq $0x0, -0x38(%rbp)
je 0x89d11
leaq -0x78(%rbp), %rdi
leaq -0x118(%rbp), %rsi
xorl %edx, %edx
callq 0x86d00
cmpl $0x0, %eax
jne 0x89a9a
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
leaq -0x78(%rbp), %rdi
leaq -0x120(%rbp), %rsi
xorl %edx, %edx
callq 0x86d00
cmpl $0x0, %eax
jne 0x89abd
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
movq -0x118(%rbp), %rax
cmpq 0x10(%rbp), %rax
seta %al
andb $0x1, %al
movzbl %al, %eax
movq -0x120(%rbp), %rcx
cmpq 0x10(%rbp), %rcx
seta %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
movq -0x118(%rbp), %rcx
addq -0x120(%rbp), %rcx
cmpq 0x10(%rbp), %rcx
seta %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
cmpl $0x0, %eax
je 0x89b14
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
movq -0x40(%rbp), %rax
addq -0x118(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rax
addq -0x120(%rbp), %rax
movq %rax, -0x110(%rbp)
cmpq $0x0, 0x28(%rbp)
je 0x89b5f
movq 0x28(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x89b5f
movq 0x28(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq *%rax
movq -0x40(%rbp), %rsi
movq -0x110(%rbp), %rdx
leaq -0x78(%rbp), %rdi
callq 0x86dd0
cmpl $0x0, %eax
jne 0x89b84
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
cmpq $0x0, 0x28(%rbp)
je 0x89ba4
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x108(%rbp), %rdx
callq *%rax
movq -0x40(%rbp), %rsi
movq -0x108(%rbp), %rdx
leaq -0xd8(%rbp), %rdi
callq 0x8a280
movq -0x108(%rbp), %rsi
movq -0x110(%rbp), %rdx
leaq -0x100(%rbp), %rdi
callq 0x8a2b0
leaq -0xd8(%rbp), %rdi
callq 0x8a300
cmpl $0x0, %eax
je 0x89d0c
leaq -0xd8(%rbp), %rdi
callq 0x8a0c0
cmpl $0x0, %eax
jne 0x89c07
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
movq -0xb0(%rbp), %rax
cmpq -0xc0(%rbp), %rax
jbe 0x89c48
movq -0xb0(%rbp), %rdx
subq -0xc0(%rbp), %rdx
leaq -0xa0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x876e0
cmpl $0x0, %eax
jne 0x89c46
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
jmp 0x89c48
movq -0x38(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0xa8(%rbp)
je 0x89cf2
movq -0xb8(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x8(%rcx), %rax
seta %al
andb $0x1, %al
movzbl %al, %eax
movq -0xa8(%rbp), %rcx
movq -0x18(%rbp), %rdx
movq 0x8(%rdx), %rdx
subq -0xb8(%rbp), %rdx
cmpq %rdx, %rcx
seta %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
cmpl $0x0, %eax
je 0x89cae
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
movq -0x18(%rbp), %rdx
movq -0xb8(%rbp), %rcx
movq -0xa8(%rbp), %r8
movq 0x18(%rbp), %r9
movq -0x48(%rbp), %rax
leaq -0xa0(%rbp), %rdi
leaq -0x100(%rbp), %rsi
movq %rax, (%rsp)
callq 0x8a330
cmpl $0x0, %eax
jne 0x89cf0
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
jmp 0x89d07
cmpq $0x0, -0x38(%rbp)
je 0x89d05
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
jmp 0x89d07
jmp 0x89bd5
jmp 0x89a6c
leaq -0xa0(%rbp), %rdi
callq 0x87300
cmpl $0x0, %eax
jne 0x89d2b
movl $0x0, -0x4(%rbp)
jmp 0x89d8c
movq -0x70(%rbp), %rcx
subq -0x78(%rbp), %rcx
movq -0x50(%rbp), %rax
subq -0x58(%rbp), %rax
addq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x124(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x8a420
movl %eax, %ecx
movl -0x124(%rbp), %eax
andl %ecx, %eax
cmpq $0x0, -0x38(%rbp)
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x89d85
movl $0x1, -0x4(%rbp)
jmp 0x89d8c
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
nopl (%rax,%rax)