// File: AraKhachatryan[P]messenger/encode_decode.cpp
// Function: encode_message(char const*, char*, unsigned long)
void encode_message( const char * input, char * output, size_t io_buffer_length )
{
    // check for private mode pattern
    bool is_private = 0;
    for( size_t i = 0; i < 100; ++i )
    {
        if ( input[0] == '@' && input[i] == ':'  )
        {
            is_private = 1;
            break;
        }
    }


    if( is_private )
    {
        size_t i = 0;
        size_t j = 0;

        // Destination names part    //////////////////////////////////////////
        bool name_end_flag = 0;
        bool name_start_flag = 0;
        bool at_last_one_name_exist = 0;

        while( input[i] != ':' )
        {
            // destination name validation
            if ( ((input[i] >= '0' && input[i] <= '9') ||
                 (input[i] >= 'A' && input[i] <= 'Z') ||
                 (input[i] >= 'a' && input[i] <= 'z')) && !name_end_flag )
            {
                if( name_start_flag && at_last_one_name_exist )
                {
                    output[j] = ',';
                    ++j;
                }
                output[j] = input[i];
                ++j;

                name_start_flag = 0;
                at_last_one_name_exist = 1;
            // for more destination names
            } else if ( input[i] == '@' ) {
                name_end_flag = 0;
                name_start_flag = 1;

            // destination name ended
            } else {
                name_end_flag = 1;
            }
            ++i;
        }

        // fill output[] after destination names with 0x00
        // destination names part can contain up to 100 simbols
        for( ; j < 100; )
        {
            output[j] = 0x00;
            ++j;
        }

        ++i; // for going over ':'

        // for going over spaces after ':'
        while( input[i] == ' ' )
        {
            ++i;
        }
        // END destination names part /////////////////////////////////////////


        // Message info part    ///////////////////////////////////////////////
        if( at_last_one_name_exist )
        {
            for( auto c: "Private" ){
                output[j] = c;
                ++j;
            }
            // fill output[] after Message info part with 0x00
            // Message info part can contain up to 28 simbols
            for( ; j < 128; )
            {
                output[j] = 0x00;
                ++j;
            }
        } else {
            for( auto c: "Public" ){
                output[j] = c;
                ++j;
            }
            // fill output[] after Message info part with 0x00
            // Message info part can contain up to 28 simbols
            for( ; j < 128; )
            {
                output[j] = 0x00;
                ++j;
            }
        }
        // END message info part //////////////////////////////////////////////


        // Message part    ////////////////////////////////////////////////////
        // copy input message to output from position 128 until reaching 0x00
        for( j = 128; j < io_buffer_length; ++i )
        {
            if( input[i] == 0x00 )
            {
                break;
            }
            output[j] = input[i];
            ++j;
        }

        // fill output[] after destination message
        for( ; j < io_buffer_length; )
        {
            output[j] = 0x00;
             ++j;
        }
        // END message part ///////////////////////////////////////////////////

    }



    if ( !is_private )
    {
        // Message info part    ///////////////////////////////////////////////
        size_t j = 100;
        for( auto c: "Public" ){
            output[j] = c;
            ++j;
        }
        // fill output[] after Message info part with 0x00
        // Message info part can contain up to 28 simbols
        for( ; j < 128; )
        {
            output[j] = 0x00;
            ++j;
        }
        // END message info part //////////////////////////////////////////////


        // Message part    ////////////////////////////////////////////////////
        // if no destination names, copy whole input to output from position 128
        j = 128;
        for( size_t i = 0; i < io_buffer_length; ++i )
        {
            output[j] = input[i];
            ++j;
        }
        // END message part ///////////////////////////////////////////////////
    }


}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movb $0x0, -0x19(%rbp)
movq $0x0, -0x28(%rbp)
cmpq $0x64, -0x28(%rbp)
jae 0x41aa
movq -0x8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x40, %eax
jne 0x419a
movq -0x8(%rbp), %rax
movq -0x28(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3a, %eax
jne 0x419a
movb $0x1, -0x19(%rbp)
jmp 0x41aa
jmp 0x419c
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x4170
testb $0x1, -0x19(%rbp)
je 0x44bb
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movb $0x0, -0x39(%rbp)
movb $0x0, -0x3a(%rbp)
movb $0x0, -0x3b(%rbp)
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3a, %eax
je 0x42d3
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x30, %eax
jl 0x4207
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x39, %eax
jle 0x424b
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x41, %eax
jl 0x4229
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x5a, %eax
jle 0x424b
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x61, %eax
jl 0x42a1
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x7a, %eax
jg 0x42a1
testb $0x1, -0x39(%rbp)
jne 0x42a1
testb $0x1, -0x3a(%rbp)
je 0x4275
testb $0x1, -0x3b(%rbp)
je 0x4275
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb $0x2c, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movb $0x0, -0x3a(%rbp)
movb $0x1, -0x3b(%rbp)
jmp 0x42c2
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x40, %eax
jne 0x42bc
movb $0x0, -0x39(%rbp)
movb $0x1, -0x3a(%rbp)
jmp 0x42c0
movb $0x1, -0x39(%rbp)
jmp 0x42c2
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x41d0
jmp 0x42d5
cmpq $0x64, -0x38(%rbp)
jae 0x42f6
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x42d5
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x20, %eax
jne 0x4321
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x4302
testb $0x1, -0x3b(%rbp)
je 0x43b6
leaq 0x1df3(%rip), %rax      # 0x6125
movq %rax, -0x48(%rbp)
leaq 0x1de8(%rip), %rax      # 0x6125
movq %rax, -0x50(%rbp)
leaq 0x1ddd(%rip), %rax      # 0x6125
addq $0x8, %rax
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x58(%rbp), %rax
je 0x438b
movq -0x50(%rbp), %rax
movb (%rax), %al
movb %al, -0x59(%rbp)
movb -0x59(%rbp), %dl
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x4350
jmp 0x438d
cmpq $0x80, -0x38(%rbp)
jae 0x43b1
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x438d
jmp 0x443e
leaq 0x1d74(%rip), %rax      # 0x6131
movq %rax, -0x68(%rbp)
leaq 0x1d69(%rip), %rax      # 0x6131
movq %rax, -0x70(%rbp)
leaq 0x1d5e(%rip), %rax      # 0x6131
addq $0x7, %rax
movq %rax, -0x78(%rbp)
movq -0x70(%rbp), %rax
cmpq -0x78(%rbp), %rax
je 0x4416
movq -0x70(%rbp), %rax
movb (%rax), %al
movb %al, -0x79(%rbp)
movb -0x79(%rbp), %dl
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0x43db
jmp 0x4418
cmpq $0x80, -0x38(%rbp)
jae 0x443c
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x4418
jmp 0x443e
movq $0x80, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x4493
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x4463
jmp 0x4493
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x4446
jmp 0x4495
movq -0x38(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x44b9
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x4495
jmp 0x44bb
testb $0x1, -0x19(%rbp)
jne 0x45f0
movq $0x64, -0x88(%rbp)
leaq 0x1c5a(%rip), %rax      # 0x6131
movq %rax, -0x90(%rbp)
leaq 0x1c4c(%rip), %rax      # 0x6131
movq %rax, -0x98(%rbp)
leaq 0x1c3e(%rip), %rax      # 0x6131
addq $0x7, %rax
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rax
cmpq -0xa0(%rbp), %rax
je 0x4557
movq -0x98(%rbp), %rax
movb (%rax), %al
movb %al, -0xa1(%rbp)
movb -0xa1(%rbp), %dl
movq -0x10(%rbp), %rax
movq -0x88(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x44fe
jmp 0x4559
cmpq $0x80, -0x88(%rbp)
jae 0x4589
movq -0x10(%rbp), %rax
movq -0x88(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0x4559
movq $0x80, -0x88(%rbp)
movq $0x0, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x45ee
movq -0x8(%rbp), %rax
movq -0xb0(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x10(%rbp), %rax
movq -0x88(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movq -0xb0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb0(%rbp)
jmp 0x459f
jmp 0x45f0
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)