// File: sisong[P]ApkDiffPatch/HDiffPatch/libHDiffPatch/HPatch/patch.c
// Function: TDiffToSingleStream_read
static hpatch_BOOL _TDiffToSingleStream_read(const struct hpatch_TStreamInput* stream,hpatch_StreamPos_t readFromPos,
                                           unsigned char* out_data,unsigned char* out_data_end){
    //[                                                         |readedSize                  ]
    //     [     |cachedBufBegin   _TDiffToSingleStream_kBufSize]
    //                                 readFromPos[out_data       out_data_end]
    TDiffToSingleStream* self=(TDiffToSingleStream*)stream->streamImport;
    hpatch_StreamPos_t readedSize=self->readedSize;
    while (1){
        size_t rLen=out_data_end-out_data;
        if (readFromPos==readedSize){
            hpatch_BOOL result=self->diffStream->read(self->diffStream,readedSize,out_data,out_data_end);
            self->readedSize=readedSize+rLen;
            if ((self->isInSingleStream)||(rLen>_TDiffToSingleStream_kBufSize)){
                self->cachedBufBegin=_TDiffToSingleStream_kBufSize;
            }else{
                //cache
                if (rLen>=_TDiffToSingleStream_kBufSize){
                    memcpy(self->buf,out_data_end-_TDiffToSingleStream_kBufSize,_TDiffToSingleStream_kBufSize);
                    self->cachedBufBegin = 0;
                }else{
                    size_t new_cachedBufBegin;
                    if (self->cachedBufBegin>=rLen){
                        new_cachedBufBegin=self->cachedBufBegin-rLen;
                        memmove(self->buf+new_cachedBufBegin,self->buf+self->cachedBufBegin,_TDiffToSingleStream_kBufSize-self->cachedBufBegin);
                    }else{
                        new_cachedBufBegin=0;
                        memmove(self->buf,self->buf+rLen,_TDiffToSingleStream_kBufSize-rLen);
                    }
                    memcpy(self->buf+(_TDiffToSingleStream_kBufSize-rLen),out_data,rLen);
                    self->cachedBufBegin=new_cachedBufBegin;
                }
            }
            return result;
        }else{
            size_t cachedSize=_TDiffToSingleStream_kBufSize-self->cachedBufBegin;
            size_t bufSize=(size_t)(readedSize-readFromPos);
            if ((readFromPos<readedSize)&(bufSize<=cachedSize)){
                if (rLen>bufSize)
                    rLen=bufSize;
                memcpy(out_data,self->buf+(_TDiffToSingleStream_kBufSize-bufSize),rLen);
                out_data+=rLen;
                readFromPos+=rLen;
                if (out_data==out_data_end) 
                    return hpatch_TRUE;
                else
                    continue;
            }else{
                return _hpatch_FALSE;
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq -0x20(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
cmpq -0x38(%rbp), %rax
jne 0x8a660
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x10(%rax), %rax
movq -0x30(%rbp), %rcx
movq 0x20(%rcx), %rdi
movq -0x38(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
callq *%rax
movl %eax, -0x44(%rbp)
movq -0x38(%rbp), %rcx
addq -0x40(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x30(%rbp), %rax
cmpl $0x0, 0x38(%rax)
jne 0x8a565
cmpq $0x1000, -0x40(%rbp)    # imm = 0x1000
jbe 0x8a576
movq -0x30(%rbp), %rax
movq $0x1000, 0x30(%rax)     # imm = 0x1000
jmp 0x8a655
cmpq $0x1000, -0x40(%rbp)    # imm = 0x1000
jb 0x8a5ae
movq -0x30(%rbp), %rdi
addq $0x3c, %rdi
movq -0x28(%rbp), %rsi
addq $-0x1000, %rsi          # imm = 0xF000
movl $0x1000, %edx           # imm = 0x1000
callq 0x4320
movq -0x30(%rbp), %rax
movq $0x0, 0x30(%rax)
jmp 0x8a653
movq -0x30(%rbp), %rax
movq 0x30(%rax), %rax
cmpq -0x40(%rbp), %rax
jb 0x8a5fc
movq -0x30(%rbp), %rax
movq 0x30(%rax), %rax
subq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rdi
addq $0x3c, %rdi
addq -0x50(%rbp), %rdi
movq -0x30(%rbp), %rsi
addq $0x3c, %rsi
movq -0x30(%rbp), %rax
addq 0x30(%rax), %rsi
movq -0x30(%rbp), %rax
movl $0x1000, %edx           # imm = 0x1000
subq 0x30(%rax), %rdx
callq 0x45c0
jmp 0x8a626
movq $0x0, -0x50(%rbp)
movq -0x30(%rbp), %rdi
addq $0x3c, %rdi
movq -0x30(%rbp), %rsi
addq $0x3c, %rsi
addq -0x40(%rbp), %rsi
movl $0x1000, %edx           # imm = 0x1000
subq -0x40(%rbp), %rdx
callq 0x45c0
movq -0x30(%rbp), %rdi
addq $0x3c, %rdi
movl $0x1000, %eax           # imm = 0x1000
subq -0x40(%rbp), %rax
addq %rax, %rdi
movq -0x20(%rbp), %rsi
movq -0x40(%rbp), %rdx
callq 0x4320
movq -0x50(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x8a655
movl -0x44(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x8a70f
movq -0x30(%rbp), %rcx
movl $0x1000, %eax           # imm = 0x1000
subq 0x30(%rcx), %rax
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
subq -0x18(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rax
cmpq -0x38(%rbp), %rax
setb %al
andb $0x1, %al
movzbl %al, %eax
movq -0x60(%rbp), %rcx
cmpq -0x58(%rbp), %rcx
setbe %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x8a708
movq -0x40(%rbp), %rax
cmpq -0x60(%rbp), %rax
jbe 0x8a6b7
movq -0x60(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rsi
addq $0x3c, %rsi
movl $0x1000, %eax           # imm = 0x1000
subq -0x60(%rbp), %rax
addq %rax, %rsi
movq -0x40(%rbp), %rdx
callq 0x4320
movq -0x40(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x40(%rbp), %rax
addq -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x28(%rbp), %rax
jne 0x8a703
movl $0x1, -0x4(%rbp)
jmp 0x8a70f
jmp 0x8a4ff
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax,%rax)