// File: Infinidat[P]slimfastq/recs.cpp
// Function: RecLoad::load(unsigned char*, unsigned char const*)
size_t RecLoad::load(UCHAR* buf, const UCHAR* prev) {
    rarely_if(not m_last.initilized) {
        comp_version = conf.decoder_version;
        bzero(ctype[0], sizeof(ctype[0])); // clear cache
        bzero(ctype[1], sizeof(ctype[1])); // clear cache
        imap = 0;
        return load_first_line(buf);
    }

    bool pmap = imap;
    imap = imap ? 0 : 1;

    rarely_if(m_last.index == g_record_count) {

        UCHAR* b = x_file->get_str(buf);
        m_last.index += x_file->get();
        bzero(ctype[imap], sizeof(ctype[imap])); // clear cache

        return b - buf;
    }

    map_space(prev, 0);         // TODO? optimize by caching prev

    rarely_if (comp_version < 5)
        return load_pre5(buf, prev);

    UINT64 map = get_num(0);
    UCHAR* b = buf;

    for (int i = 0; i < smap[0].len; i++) {
        // if (IS_SET(last_map, i)) {
        if (not IS_SET(map, i)) {
            // b = (UCHAR*)mempcpy(b, prev + smap[0].off[i], smap[0].wln[i]);
            // mempcpy is not compatible with Mac OS, must do it the hard way ..
            UINT32 count = smap[0].wln[i] ;
            memcpy(b, prev + smap[0].off[i], count );
            b += count;
            *b ++ = smap[0].str[i];
            ctype[imap][i] = ctype[pmap][i];
            cnumb[imap][i] = cnumb[pmap][i];
            continue;
        }

        UCHAR type = get_type(i+1);

        if ( type == ST_STR ) {
            b = get_str(i+1, b);
            ctype[imap][i] = 0;
            *b ++ = smap[0].str[i];
            continue;
        }

        UINT64 pval = ctype[pmap][i] == 0 ? 0 : cnumb[pmap][i];
        UINT64 gap = get_num(i+1);
        UINT64 val ;
        const char* fmt;
#define ITEM(A, B) fmt=A; val=B; break
        switch ((seg_type)type) {

        case ST_DGT    : ITEM("%lld", pval + gap);
        case ST_DLT    : ITEM("%lld", pval - gap);
        case ST_STR    :   croak("WTF"); break;
        case ST_HGT    : ITEM("%llx", pval + gap);
        case ST_HLT    : ITEM("%llx", pval - gap);
        case ST_HGT_Z  : ITEM("0%llx", pval + gap);
        case ST_HLT_Z  : ITEM("0%llx", pval - gap);
        case ST_HGTC   : ITEM("%llX", pval + gap);
        case ST_HLTC   : ITEM("%llX", pval - gap);
        case ST_HGTC_Z : ITEM("0%llX", pval + gap);
        case ST_HLTC_Z : ITEM("0%llX", pval - gap);
        case ST_DGT_Z  : ITEM("0%lld", pval + gap);
        case ST_DLT_Z  : ITEM("0%lld", pval - gap);

        default:
            croak("REC: bad type value %d", type);
        }
#undef ITEM
        ctype[imap][i] = (type < ST_STR or type >= ST_DGT_Z) ? 1 : 2;
        cnumb[imap][i] = val;
        if (val == 0)
            *b ++ = '0'; // Under certain conditions sprintf(b, '%lld', 0) was printing "00". Yack!
        else
            b += sprintf((char*)b, fmt, val);

        *b ++ = smap[0].str[i];
    }
    return b-buf-1;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movq %rdx, 0x78(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x20(%rsp)
movb 0xc7d08(%rax), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xb9e7
jmp 0xba51
movq 0x20(%rsp), %rdi
leaq 0xc9ed(%rip), %rax      # 0x183e0
movl 0x8(%rax), %eax
movl %eax, 0xc8664(%rdi)
addq $0xc81c8, %rdi          # imm = 0xC81C8
xorl %esi, %esi
movl $0x41, %edx
callq 0x2170
movq 0x20(%rsp), %rdi
addq $0xc81c8, %rdi          # imm = 0xC81C8
addq $0x41, %rdi
xorl %esi, %esi
movl $0x41, %edx
callq 0x2170
movq 0x20(%rsp), %rdi
movb $0x0, 0xc8660(%rdi)
movq 0x80(%rsp), %rsi
callq 0xaa30
movq %rax, 0x90(%rsp)
jmp 0xc0da
movq 0x20(%rsp), %rax
movb 0xc8660(%rax), %cl
andb $0x1, %cl
movb %cl, 0x77(%rsp)
movb 0xc8660(%rax), %sil
movl $0x1, %ecx
xorl %edx, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movb %cl, 0xc8660(%rax)
movq 0xc7d10(%rax), %rax
leaq 0xa7cb(%rip), %rcx      # 0x16260
cmpq (%rcx), %rax
jne 0xbb2b
movq 0x20(%rsp), %rax
movq 0xc8670(%rax), %rdi
movq 0x80(%rsp), %rsi
callq 0xfc40
movq %rax, %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x68(%rsp)
movq 0xc8670(%rax), %rdi
callq 0xfb60
movq %rax, %rcx
movq 0x20(%rsp), %rax
addq 0xc7d10(%rax), %rcx
movq %rcx, 0xc7d10(%rax)
movq %rax, %rdi
addq $0xc81c8, %rdi          # imm = 0xC81C8
movb 0xc8660(%rax), %al
andb $0x1, %al
movzbl %al, %eax
imulq $0x41, %rax, %rax
addq %rax, %rdi
xorl %esi, %esi
movl $0x41, %edx
callq 0x2170
movq 0x68(%rsp), %rax
movq 0x80(%rsp), %rcx
subq %rcx, %rax
movq %rax, 0x90(%rsp)
jmp 0xc0da
movq 0x20(%rsp), %rdi
movq 0x78(%rsp), %rsi
xorl %edx, %edx
callq 0xabb0
movq 0x20(%rsp), %rax
cmpl $0x5, 0xc8664(%rax)
jge 0xbb6e
movq 0x20(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x78(%rsp), %rdx
callq 0xc0f0
movq %rax, 0x90(%rsp)
jmp 0xc0da
movq 0x20(%rsp), %rdi
xorl %esi, %esi
callq 0xaac0
movq %rax, 0x60(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x58(%rsp)
movl $0x0, 0x54(%rsp)
movq 0x20(%rsp), %rcx
movl 0x54(%rsp), %eax
movzbl 0xc7f79(%rcx), %ecx
cmpl %ecx, %eax
jge 0xc0be
movq 0x60(%rsp), %rax
movq %rax, 0x18(%rsp)
movl 0x54(%rsp), %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq 0x18(%rsp), %rcx
andq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jne 0xbce3
movq 0x20(%rsp), %rax
movslq 0x54(%rsp), %rcx
movl 0xc7e34(%rax,%rcx,4), %ecx
movl %ecx, 0x50(%rsp)
movq 0x58(%rsp), %rdi
movq 0x78(%rsp), %rsi
movslq 0x54(%rsp), %rcx
movslq 0xc7d30(%rax,%rcx,4), %rax
addq %rax, %rsi
movl 0x50(%rsp), %eax
movl %eax, %edx
callq 0x2220
movq 0x20(%rsp), %rcx
movl 0x50(%rsp), %edx
movq 0x58(%rsp), %rax
movl %edx, %edx
addq %rdx, %rax
movq %rax, 0x58(%rsp)
movslq 0x54(%rsp), %rax
movb 0xc7f38(%rcx,%rax), %dl
movq 0x58(%rsp), %rax
movq %rax, %rsi
addq $0x1, %rsi
movq %rsi, 0x58(%rsp)
movb %dl, (%rax)
movq %rcx, %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0x77(%rsp), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x41, %rdx, %rdx
addq %rdx, %rax
movslq 0x54(%rsp), %rdx
movb (%rax,%rdx), %sil
movq %rcx, %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0xc8660(%rcx), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x41, %rdx, %rdx
addq %rdx, %rax
movslq 0x54(%rsp), %rdx
movb %sil, (%rax,%rdx)
movq %rcx, %rax
addq $0xc8250, %rax          # imm = 0xC8250
movb 0x77(%rsp), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x208, %rdx, %rdx      # imm = 0x208
addq %rdx, %rax
movslq 0x54(%rsp), %rdx
movq (%rax,%rdx,8), %rdx
movq %rcx, %rax
addq $0xc8250, %rax          # imm = 0xC8250
movb 0xc8660(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x208, %rcx, %rcx      # imm = 0x208
addq %rcx, %rax
movslq 0x54(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0xc0ae
movq 0x20(%rsp), %rdi
movl 0x54(%rsp), %eax
addl $0x1, %eax
movzbl %al, %esi
callq 0xaa80
movb %al, 0x4f(%rsp)
movzbl 0x4f(%rsp), %eax
cmpl $0x2, %eax
jne 0xbd75
movq 0x20(%rsp), %rdi
movl 0x54(%rsp), %eax
addl $0x1, %eax
movq 0x58(%rsp), %rdx
movzbl %al, %esi
callq 0xab00
movq %rax, %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x58(%rsp)
movq %rax, %rcx
addq $0xc81c8, %rcx          # imm = 0xC81C8
movb 0xc8660(%rax), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x41, %rdx, %rdx
addq %rdx, %rcx
movslq 0x54(%rsp), %rdx
movb $0x0, (%rcx,%rdx)
movslq 0x54(%rsp), %rcx
movb 0xc7f38(%rax,%rcx), %cl
movq 0x58(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x58(%rsp)
movb %cl, (%rax)
jmp 0xc0ae
movq 0x20(%rsp), %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0x77(%rsp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x41, %rcx, %rcx
addq %rcx, %rax
movslq 0x54(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0xbda8
xorl %eax, %eax
movq %rax, 0x10(%rsp)
jmp 0xbdd5
movq 0x20(%rsp), %rax
addq $0xc8250, %rax          # imm = 0xC8250
movb 0x77(%rsp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x208, %rcx, %rcx      # imm = 0x208
addq %rcx, %rax
movslq 0x54(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x10(%rsp)
movq 0x20(%rsp), %rdi
movq 0x10(%rsp), %rax
movq %rax, 0x40(%rsp)
movl 0x54(%rsp), %eax
incl %eax
movzbl %al, %esi
callq 0xaac0
movq %rax, 0x38(%rsp)
movzbl 0x4f(%rsp), %eax
movq %rax, 0x8(%rsp)
subq $0xc, %rax
ja 0xbfa2
movq 0x8(%rsp), %rax
leaq 0x5221(%rip), %rcx      # 0x11038
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x4dca(%rip), %rax      # 0x10bf1
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
addq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x4daa(%rip), %rax      # 0x10bf1
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
subq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x5295(%rip), %rdi      # 0x110fc
movb $0x0, %al
callq 0x3450
leaq 0x528c(%rip), %rax      # 0x11101
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
addq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x526c(%rip), %rax      # 0x11101
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
subq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x524b(%rip), %rax      # 0x11100
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
addq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x522b(%rip), %rax      # 0x11100
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
subq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x5212(%rip), %rax      # 0x11107
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
addq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x51f2(%rip), %rax      # 0x11107
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
subq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x51d1(%rip), %rax      # 0x11106
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
addq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x51b4(%rip), %rax      # 0x11106
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
subq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x519d(%rip), %rax      # 0x1110c
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
addq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
leaq 0x5180(%rip), %rax      # 0x1110c
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
subq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
jmp 0xbfb5
movzbl 0x4f(%rsp), %esi
leaq 0x5164(%rip), %rdi      # 0x11112
movb $0x0, %al
callq 0x3450
movzbl 0x4f(%rsp), %ecx
movb $0x1, %al
cmpl $0x2, %ecx
movb %al, 0x7(%rsp)
jl 0xbfd4
movzbl 0x4f(%rsp), %eax
cmpl $0xb, %eax
setge %al
movb %al, 0x7(%rsp)
movq 0x20(%rsp), %rcx
movb 0x7(%rsp), %sil
movl $0x2, %eax
movl $0x1, %edx
testb $0x1, %sil
cmovnel %edx, %eax
movb %al, %sil
movq %rcx, %rax
addq $0xc81c8, %rax          # imm = 0xC81C8
movb 0xc8660(%rcx), %dl
andb $0x1, %dl
movzbl %dl, %edx
imulq $0x41, %rdx, %rdx
addq %rdx, %rax
movslq 0x54(%rsp), %rdx
movb %sil, (%rax,%rdx)
movq 0x30(%rsp), %rdx
movq %rcx, %rax
addq $0xc8250, %rax          # imm = 0xC8250
movb 0xc8660(%rcx), %cl
andb $0x1, %cl
movzbl %cl, %ecx
imulq $0x208, %rcx, %rcx      # imm = 0x208
addq %rcx, %rax
movslq 0x54(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
cmpq $0x0, 0x30(%rsp)
jne 0xc062
movq 0x58(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x58(%rsp)
movb $0x30, (%rax)
jmp 0xc08a
movq 0x58(%rsp), %rdi
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
movb $0x0, %al
callq 0x20b0
movl %eax, %ecx
movq 0x58(%rsp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x58(%rsp)
movq 0x20(%rsp), %rax
movslq 0x54(%rsp), %rcx
movb 0xc7f38(%rax,%rcx), %cl
movq 0x58(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x58(%rsp)
movb %cl, (%rax)
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0xbb94
movq 0x58(%rsp), %rax
movq 0x80(%rsp), %rcx
subq %rcx, %rax
subq $0x1, %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
addq $0x98, %rsp
retq
nopw (%rax,%rax)