// File: /workspace/github_cpp_makefile_star2_O1/night-shift[P]Srl/src/lib/ToolsBtsConv.cpp
// Function: Srl::Tools::bytes_to_base64(unsigned char const*, unsigned long, std::vector<unsigned char, std::allocator<unsigned char>>&)
size_t Tools::bytes_to_base64(const uint8_t* bytes, size_t nbytes, vector<uint8_t>& out)
{
    auto min_size = 4 * ((nbytes + 2) / 3);

    if(out.size() < min_size) {
        out.resize(min_size);
    }

    Base64Table table;
    uint8_t b0 = 0, b1 = 0, b2 = 0;

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

        b0 = bytes[in_idx];
        b1 = in_idx + 1 < nbytes ? bytes[in_idx + 1] : 0;
        b2 = in_idx + 2 < nbytes ? bytes[in_idx + 2] : 0;

        /* [BBBBBB]BB BBBBBBBB BBBBBBBB */
        out[out_idx]     = table.encode[b0 >> 2];
        /* PPPPPP [BB BBBB]BBBB BBBBBBBB */
        out[out_idx + 1] = table.encode[((b0 << 4) | (b1 >> 4)) & 0x3F];
        /* PPPPPP PPPPPP [BBBB BB]BBBBBB */
        out[out_idx + 2] = table.encode[((b1 << 2) | (b2 >> 6)) & 0x3F];
        /* PPPPPP PPPPPP PPPPPP [BBBBBB] */
        out[out_idx + 3] = table.encode[b2 & 0x3F];
    }

    auto rem = nbytes % 3;
    /* rem == 1 -> 2 equals signs, rem == 2 -> 1 equals sign */
    if(rem > 0) {
        out[min_size - 1] = '=';
    }
    if(rem == 1) {
        out[min_size - 2] = '=';
    }

    return min_size;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movq %rdx, %rbx
movq %rsi, %r15
leaq 0x2(%rsi), %rax
movabsq $-0x5555555555555555, %rbp # imm = 0xAAAAAAAAAAAAAAAB
mulq %rbp
movq %rdx, %r14
movq %rdi, %r12
addq %rdx, %r14
andq $-0x4, %r14
movq 0x8(%rbx), %rax
subq (%rbx), %rax
cmpq %r14, %rax
jae 0x1b8c7
movq %rbx, %rdi
movq %r14, %rsi
callq 0xb980
leaq 0x48(%rsp), %r13
movw $0xfeff, -0x42(%r13)    # imm = 0xFEFF
movups 0x46a6(%rip), %xmm0     # 0x1ff80
movups %xmm0, -0x40(%r13)
movups 0x46aa(%rip), %xmm0     # 0x1ff90
movups %xmm0, -0x30(%r13)
movups 0x46ae(%rip), %xmm0     # 0x1ffa0
movups %xmm0, -0x20(%r13)
movups 0x46b2(%rip), %xmm0     # 0x1ffb0
movups %xmm0, -0x10(%r13)
movl $0x100, %edx            # imm = 0x100
movq %r13, %rdi
movl $0xff, %esi
callq 0xb420
movb $-0x2, 0x3d(%r13)
xorl %eax, %eax
movsbq 0x8(%rsp,%rax), %rcx
movb %al, 0x48(%rsp,%rcx)
incq %rax
cmpq $0x40, %rax
jne 0x1b91c
testq %r15, %r15
je 0x1b9d0
movl $0x2, %eax
xorl %ecx, %ecx
leaq -0x1(%rax), %rsi
movl $0x0, %edx
cmpq %r15, %rsi
jae 0x1b953
movzbl -0x1(%r12,%rax), %edx
xorl %esi, %esi
cmpq %r15, %rax
jae 0x1b95f
movzbl (%r12,%rax), %esi
movzbl -0x2(%r12,%rax), %edi
movl %edi, %r8d
shrl $0x2, %r8d
movb 0x8(%rsp,%r8), %r8b
movq (%rbx), %r9
movb %r8b, (%r9,%rcx)
shll $0x4, %edi
movl %edx, %r8d
shrl $0x4, %r8d
andl $0x30, %edi
orl %r8d, %edi
movb 0x8(%rsp,%rdi), %dil
movq (%rbx), %r8
movb %dil, 0x1(%r8,%rcx)
movl %esi, %edi
shrl $0x6, %edi
andl $0xf, %edx
leal (%rdi,%rdx,4), %edx
movb 0x8(%rsp,%rdx), %dl
movq (%rbx), %rdi
movb %dl, 0x2(%rdi,%rcx)
andl $0x3f, %esi
movb 0x8(%rsp,%rsi), %dl
movq (%rbx), %rsi
movb %dl, 0x3(%rsi,%rcx)
addq $0x4, %rcx
leaq 0x3(%rax), %rdx
incq %rax
cmpq %r15, %rax
movq %rdx, %rax
jb 0x1b93f
movq %r15, %rax
mulq %rbp
shrq %rdx
leaq (%rdx,%rdx,2), %rax
subq %rax, %r15
je 0x1b9fa
movq (%rbx), %rax
movb $0x3d, -0x1(%rax,%r14)
cmpq $0x1, %r15
jne 0x1b9fa
movq (%rbx), %rax
movb $0x3d, -0x2(%rax,%r14)
movq %r14, %rax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq