// File: night-shift[P]Srl/src/lib/ToolsBtsConv.cpp
// Function: Srl::Tools::base64_to_bytes(unsigned char*, unsigned long, char const*, unsigned long)
size_t Tools::base64_to_bytes(uint8_t* dest, size_t dest_size, const char* str, size_t str_len)
{
    Base64Table table;

    if(str_len > 0 && str_len % 4 != 0) {
        throw Exception("Unable to convert base64 string to binary data." \
                        " Size of source must be a multiple of 4." );
    }

    for(size_t in_idx = 0, out_idx = 0; out_idx < dest_size;
               out_idx += 3, in_idx += 4) {

        uint8_t b0 = table.decode[ (size_t) str[in_idx] ],
                b1 = table.decode[ (size_t) str[in_idx + 1] ],
                b2 = table.decode[ (size_t) str[in_idx + 2] ],
                b3 = table.decode[ (size_t) str[in_idx + 3] ];

        if(b0 == table.val_invalid || b1 == table.val_invalid ||
           b2 == table.val_invalid || b3 == table.val_invalid) {
            throw Exception("Unable to convert base64 string to binary data. String malformed.");
        }
        /* [BBBBBB BB]BBBB BBBBBB BBBBBB */
        dest[out_idx] = b0 << 2 | b1 >> 4;
        /* PPPPPP PP[BBBB BBBB]BB BBBBBB */
        if(out_idx + 1 < dest_size) {
            dest[out_idx + 1] = b1 << 4 | b2 >> 2;
        }
        /* PPPPPP PPPPPP PPPP[BB BBBBBB] */
        if(out_idx + 2 < dest_size) {
            dest[out_idx + 2] = b2 << 6 | b3;
        }
    }

    return get_base64_decoded_size(str, str_len);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x200, %rsp            # imm = 0x200
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
leaq -0x162(%rbp), %rdi
callq 0x381b0
cmpq $0x0, -0x20(%rbp)
jbe 0x61fb0
movq -0x20(%rbp), %rax
andq $0x3, %rax
cmpq $0x0, %rax
je 0x61fb0
movb $0x1, -0x19d(%rbp)
movl $0x28, %edi
callq 0x34160
movq %rax, -0x1f0(%rbp)
leaq -0x189(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x38240
movq -0x1e8(%rbp), %rdx
leaq 0x80f7(%rip), %rsi      # 0x6a004
leaq -0x188(%rbp), %rdi
callq 0x37f40
jmp 0x61f1b
movq -0x1f0(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x33910
jmp 0x61f30
movq -0x1f0(%rbp), %rdi
movb $0x0, -0x19d(%rbp)
movq 0x210a3(%rip), %rsi     # 0x82fe8
movq 0x20fec(%rip), %rdx     # 0x82f38
callq 0x37fc0
jmp 0x62256
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x198(%rbp)
movl %eax, -0x19c(%rbp)
jmp 0x61f88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x198(%rbp)
movl %eax, -0x19c(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x38ce0
leaq -0x189(%rbp), %rdi
callq 0x35f90
testb $0x1, -0x19d(%rbp)
jne 0x61f9f
jmp 0x61fab
movq -0x1f0(%rbp), %rdi
callq 0x34ce0
jmp 0x6224a
movq $0x0, -0x1a8(%rbp)
movq $0x0, -0x1b0(%rbp)
movq -0x1b0(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x62234
movq -0x18(%rbp), %rax
movq -0x1a8(%rbp), %rcx
movsbq (%rax,%rcx), %rax
movb -0x120(%rbp,%rax), %al
movb %al, -0x1b1(%rbp)
movq -0x18(%rbp), %rax
movq -0x1a8(%rbp), %rcx
movsbq 0x1(%rax,%rcx), %rax
movb -0x120(%rbp,%rax), %al
movb %al, -0x1b2(%rbp)
movq -0x18(%rbp), %rax
movq -0x1a8(%rbp), %rcx
movsbq 0x2(%rax,%rcx), %rax
movb -0x120(%rbp,%rax), %al
movb %al, -0x1b3(%rbp)
movq -0x18(%rbp), %rax
movq -0x1a8(%rbp), %rcx
movsbq 0x3(%rax,%rcx), %rax
movb -0x120(%rbp,%rax), %al
movb %al, -0x1b4(%rbp)
movzbl -0x1b1(%rbp), %eax
movzbl -0x162(%rbp), %ecx
cmpl %ecx, %eax
je 0x6209a
movzbl -0x1b2(%rbp), %eax
movzbl -0x162(%rbp), %ecx
cmpl %ecx, %eax
je 0x6209a
movzbl -0x1b3(%rbp), %eax
movzbl -0x162(%rbp), %ecx
cmpl %ecx, %eax
je 0x6209a
movzbl -0x1b4(%rbp), %eax
movzbl -0x162(%rbp), %ecx
cmpl %ecx, %eax
jne 0x62176
movb $0x1, -0x1da(%rbp)
movl $0x28, %edi
callq 0x34160
movq %rax, -0x200(%rbp)
leaq -0x1d9(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x38240
movq -0x1f8(%rbp), %rdx
leaq 0x7f89(%rip), %rsi      # 0x6a05c
leaq -0x1d8(%rbp), %rdi
callq 0x37f40
jmp 0x620e1
movq -0x200(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0x33910
jmp 0x620f6
movq -0x200(%rbp), %rdi
movb $0x0, -0x1da(%rbp)
movq 0x20edd(%rip), %rsi     # 0x82fe8
movq 0x20e26(%rip), %rdx     # 0x82f38
callq 0x37fc0
jmp 0x62256
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x198(%rbp)
movl %eax, -0x19c(%rbp)
jmp 0x6214e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x198(%rbp)
movl %eax, -0x19c(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0x38ce0
leaq -0x1d9(%rbp), %rdi
callq 0x35f90
testb $0x1, -0x1da(%rbp)
jne 0x62165
jmp 0x62171
movq -0x200(%rbp), %rdi
callq 0x34ce0
jmp 0x6224a
movzbl -0x1b1(%rbp), %eax
shll $0x2, %eax
movzbl -0x1b2(%rbp), %ecx
sarl $0x4, %ecx
orl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x1b0(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x1b0(%rbp), %rax
addq $0x1, %rax
cmpq -0x10(%rbp), %rax
jae 0x621d4
movzbl -0x1b2(%rbp), %eax
shll $0x4, %eax
movzbl -0x1b3(%rbp), %ecx
sarl $0x2, %ecx
orl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x1b0(%rbp), %rcx
movb %dl, 0x1(%rax,%rcx)
movq -0x1b0(%rbp), %rax
addq $0x2, %rax
cmpq -0x10(%rbp), %rax
jae 0x62209
movzbl -0x1b3(%rbp), %eax
shll $0x6, %eax
movzbl -0x1b4(%rbp), %ecx
orl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x1b0(%rbp), %rcx
movb %dl, 0x2(%rax,%rcx)
jmp 0x6220b
movq -0x1b0(%rbp), %rax
addq $0x3, %rax
movq %rax, -0x1b0(%rbp)
movq -0x1a8(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x1a8(%rbp)
jmp 0x61fc6
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x37850
addq $0x200, %rsp            # imm = 0x200
popq %rbp
retq
movq -0x198(%rbp), %rdi
callq 0x38210
nopw %cs:(%rax,%rax)