// File: sisong[P]ApkDiffPatch/HDiffPatch/libHDiffPatch/HDiff/diff.cpp
// Function: (anonymous namespace)::getBestMatch(long*, hdiff_private::TSuffixString const&, unsigned char const*, unsigned char const*, long, (anonymous namespace)::TDiffLimit*, unsigned long*)
static TInt getBestMatch(TInt* out_pos,const TSuffixString& sstring,
                         const TByte* newData,const TByte* newData_end,
                         TInt curNewPos,TDiffLimit* diffLimit=0,size_t* out_limitSkip=0){
    TInt sai=sstring.lower_bound(newData,newData_end);
    if (sai<0) return 0;
    const TInt matchDeep = diffLimit?diffLimit->kMaxMatchDeep:2;
    const TInt kLimitOldPos=(TInt)(diffLimit?diffLimit->recoverOldPos:0);
    const TInt kLimitOldEnd=(TInt)(diffLimit?diffLimit->recoverOldEnd:sstring.SASize());
    
    const TByte* src_begin=sstring.src_begin();
    const TByte* src_end=sstring.src_end();
    TInt bestLength= kMinMatchLen -1;
    TInt bestOldPos=-1;
    bool leftOk = false;
    bool rightOk = false;
    for (TInt mdi= 0; mdi< matchDeep; ++mdi) {
        if (mdi&1){
            if (rightOk) continue;
        } else {
            if (leftOk) continue;
        }
        TInt i = sai + (1-(mdi&1)*2) * ((mdi+1)/2);
        if ((i<0)|(i>=(src_end-src_begin))) continue;
        TInt curOldPos=sstring.SA(i);

        TInt curLength;
        #define kTryEqLenLimit (1024*1+17)
        if (0==diffLimit){
            curLength=getEqualLength(newData,newData_end,src_begin+curOldPos,src_end);
        }else{
            curLength=getEqualLengthLimit<kTryEqLenLimit>(newData,newData_end,src_begin+curOldPos,src_end);
            if ((kLimitOldPos<=curOldPos)&&(curOldPos<kLimitOldEnd)){
                if (curLength==kTryEqLenLimit)
                    *out_limitSkip=kTryEqLenLimit/2;
                continue;
            }
        }
         
        if (curLength>bestLength){
            if (diffLimit){
                hpatch_TCover cover={(size_t)curOldPos,(size_t)curNewPos,(size_t)curLength};
                hpatch_StreamPos_t hitPos;
                diffLimit->listener->limitCover(diffLimit->listener,&cover,&hitPos);
                if (hitPos<=(size_t)bestLength)
                    continue;
                if (hitPos==kTryEqLenLimit){
                    curLength=getEqualLength(newData,newData_end,src_begin+curOldPos,src_end);
                    hpatch_TCover cover={(size_t)curOldPos,(size_t)curNewPos,(size_t)curLength};
                    diffLimit->listener->limitCover(diffLimit->listener,&cover,&hitPos);
                }
                curLength=(TInt)hitPos;
            }
            bestLength = curLength;
            bestOldPos= curOldPos;
        }
        if (mdi&1){
            rightOk=true; if (leftOk) break;
        } else {
            leftOk=true; if (rightOk) break;
        }
    }
    *out_pos=bestOldPos;
    return  bestLength;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
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), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x39d40
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jge 0x23000
movq $0x0, -0x8(%rbp)
jmp 0x2339c
cmpq $0x0, -0x38(%rbp)
je 0x23016
movq -0x38(%rbp), %rax
movl 0x50(%rax), %eax
movl %eax, -0xdc(%rbp)
jmp 0x23023
movl $0x2, %eax
movl %eax, -0xdc(%rbp)
jmp 0x23023
movl -0xdc(%rbp), %eax
cltq
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x23047
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0xe8(%rbp)
jmp 0x23052
xorl %eax, %eax
movq %rax, -0xe8(%rbp)
jmp 0x23052
movq -0xe8(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x23075
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0xf0(%rbp)
jmp 0x23085
movq -0x18(%rbp), %rdi
callq 0x2ad80
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2ade0
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2ae00
movq %rax, -0x68(%rbp)
movq $0x4, -0x70(%rbp)
movq $-0x1, -0x78(%rbp)
movb $0x0, -0x79(%rbp)
movb $0x0, -0x7a(%rbp)
movq $0x0, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x48(%rbp), %rax
jge 0x23389
movq -0x88(%rbp), %rax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x230fc
testb $0x1, -0x7a(%rbp)
je 0x230fa
jmp 0x23372
jmp 0x23109
testb $0x1, -0x79(%rbp)
je 0x23107
jmp 0x23372
jmp 0x23109
movq -0x40(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x88(%rbp), %rax
andq $0x1, %rax
shlq %rax
movl $0x1, %ecx
subq %rax, %rcx
movq -0x88(%rbp), %rax
addq $0x1, %rax
movl $0x2, %esi
cqto
idivq %rsi
movq %rax, %rdx
movq -0xf8(%rbp), %rax
imulq %rdx, %rcx
addq %rcx, %rax
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
setl %al
andb $0x1, %al
movzbl %al, %eax
movq -0x90(%rbp), %rcx
movq -0x68(%rbp), %rdx
movq -0x60(%rbp), %rsi
subq %rsi, %rdx
cmpq %rdx, %rcx
setge %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
cmpl $0x0, %eax
je 0x23191
jmp 0x23372
movq -0x18(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq 0x2ae20
movq %rax, -0x98(%rbp)
xorl %eax, %eax
cmpq -0x38(%rbp), %rax
jne 0x231d5
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x60(%rbp), %rdx
addq -0x98(%rbp), %rdx
movq -0x68(%rbp), %rcx
callq 0x239d0
movq %rax, -0xa0(%rbp)
jmp 0x23231
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x60(%rbp), %rdx
addq -0x98(%rbp), %rdx
movq -0x68(%rbp), %rcx
callq 0x23a80
movq %rax, -0xa0(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x98(%rbp), %rax
jg 0x2322f
movq -0x98(%rbp), %rax
cmpq -0x58(%rbp), %rax
jge 0x2322f
cmpq $0x411, -0xa0(%rbp) # imm = 0x411
jne 0x2322a
movq 0x10(%rbp), %rax
movq $0x208, (%rax)          # imm = 0x208
jmp 0x23372
jmp 0x23231
movq -0xa0(%rbp), %rax
cmpq -0x70(%rbp), %rax
jle 0x23343
cmpq $0x0, -0x38(%rbp)
je 0x2332d
movq -0x98(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq -0x38(%rbp), %rcx
movq (%rcx), %rdi
leaq -0xb8(%rbp), %rsi
leaq -0xc0(%rbp), %rdx
callq *%rax
movq -0xc0(%rbp), %rax
cmpq -0x70(%rbp), %rax
ja 0x232a7
jmp 0x23372
cmpq $0x411, -0xc0(%rbp) # imm = 0x411
jne 0x2331f
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x60(%rbp), %rdx
addq -0x98(%rbp), %rdx
movq -0x68(%rbp), %rcx
callq 0x239d0
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq -0x38(%rbp), %rcx
movq (%rcx), %rdi
leaq -0xd8(%rbp), %rsi
leaq -0xc0(%rbp), %rdx
callq *%rax
movq -0xc0(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x88(%rbp), %rax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x23362
movb $0x1, -0x7a(%rbp)
testb $0x1, -0x79(%rbp)
je 0x23360
jmp 0x23389
jmp 0x23370
movb $0x1, -0x79(%rbp)
testb $0x1, -0x7a(%rbp)
je 0x2336e
jmp 0x23389
jmp 0x23370
jmp 0x23372
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0x230cd
movq -0x78(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x70(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopl (%rax)