// File: /workspace/github_c_makefile_star2_O1/inflex[P]ripMIME/libmime-decoders.c
// Function: MDECODE_decode_quoted_printable
int MDECODE_decode_quoted_printable( char *line, int qpmode, char esc_char )
{
    char c;                             /* The Character to output */
    int op, ip;                         /* OutputPointer and InputPointer */
    int slen = strlen(line); /* Length of our line */

    DMD LOGGER_log("%s:%d:MDECODE_decode_quoted_printable:DEBUG: input string = '%s' Input length = %d\n",FL, line, slen);
    /* Initialise our "pointers" to the start of the encoded string */
    ip=op=0;
    /* for every character in the string... */
    for (ip = 0; ip < slen; ip++)
    {
        c = line[ip];
        /* if we have the quoted-printable esc char, then lets get cracking */
        if (c == esc_char)
        {
            /* if we have another two chars... */
            if ((ip +1) < slen )
            {
                int original_ip = ip;

                /* Is our next char a \n\r ?

                    if it is, then we have to eliminate any further \r\n's etc
                    so as to turn the =\n\r into a 'soft return', which basically
                    means that we ignore it.  Soft-breaks are used so we can
                    fit our long lines into the requirement of a maximum of 76 characters
                    per line.

                    So we move the input-pointer along skipping each character without
                    incrementing the output pointer.
                 */
                /** Absorb any trailing whitespaces **/
                if (1)
                {
                    char *w = &(line[ip +1]);
                    while ((*w == '\t') || (*w == ' ')) {w++;ip++;}
                }

                /** Do we now have a line break ? **/
                if (( line[ip +1] == '\n') || (line[ip +1] == '\r' ))
                {
                    ip++;
                    if ((ip+1 < slen)&&(( line[ip +1] == '\n') || (line[ip +1] == '\r' )))
                    {
                        ip++;
                    }
                    continue;
                }

                else
                {
                    /*
                        if the characters following the '=' symbol are not
                        of the \n or \r pair, then we will [currently]
                        assume that the next two characters are in fact the
                        hexadecimal encodings of the character we do want

                     */
                    /** Revert to original position **/
                    ip = original_ip;

                    /* convert our encoded character from HEX -> decimal */

                    if ( ip < slen-1 ) // was 2, proving - if there are 3 chars in string, =AB, slen = 3, ip = 1
                    {
                        /**
                         * Jan 17th 2007 jjohnston
                         * Fixed a bug that decoded invalid QP sequences
                         */
                        if(hexconv[(int)line[ip+1]] == 20 || hexconv[(int)line[ip+2]] == 20) {

                            //LOGGER_log("%s:%d:MIME_decode_quoted_printable:NOTICE: Invalid characters for quoted-printable at '=%c%c'\n", FL, (int)&line[ip+1], (int)&line[ip+2]);


                        } else {

                        c = (char)hexconv[(int)line[ip+1]]*16 +hexconv[(int)line[ip+2]];

                        /* shuffle the pointer up two spaces */
                        ip+=2;
                    }
                    }
                    else {
                        LOGGER_log("%s:%d:MIME_decode_quoted_printable:WARNING: Ran out of characters when decoding end of '%s'\n", FL, &line[ip] );
                    }
                }
            } /* if there were two extra chars after the ='s */

            /* if we didn't have enough characters, then  we'll make the char the
             * string terminator (such as what happens when we get a =\n
             */
            else
            {
                /* 2002-12-16:18H31: changed from 'line[ip]' to 'line[op]' */
                line[op] = '\0';
                /* 2002-12-16:18H32: added break statement - if we're out of chars, then we quit the for loop */
                break;
            } /* else */

        } /* if c was a encoding char */


        else
            if (( c == '_' ) && ( qpmode == MDECODE_QPMODE_ISO ))
            {
                // RFC2047  (Section 4.2.(2)(3)) says that if we encounter a '_' character in our ISO encodings then
                //  we must convert that to a space ( as we are not allowed to have spaces in any
                c = ' ';
            }

        /* put in the new character, be it converted or not */
        line[op] = c;

        /* shuffle up the output line pointer */
        op++;


    } /* for loop */

    /* terminate the line */
    line[op]='\0';
    DMD LOGGER_log("%s:%d:MDECODE_decode_quoted_printable:DEBUG: Output = '%s' Output length = %d\n", FL, line, strlen(line));
    // 2003-01-26:PLD: Changed from (op -1) -=> op
    return op;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %ebp
movl %esi, (%rsp)
movq %rdi, %rbx
callq 0x2110
movq %rax, %r12
cmpl $0x0, 0x228e0(%rip)     # 0x2f540
jle 0xcc82
leaq 0xaf57(%rip), %rdi      # 0x17bc0
leaq 0xafa4(%rip), %rsi      # 0x17c14
movl $0xc8, %edx
movq %rbx, %rcx
movl %r12d, %r8d
xorl %eax, %eax
callq 0xc960
testl %r12d, %r12d
jle 0xcdc7
leal -0x1(%r12), %r10d
leaq 0xae29(%rip), %r11      # 0x17ac0
xorl %r15d, %r15d
xorl %r14d, %r14d
movl (%rsp), %r9d
movl %ebp, 0x4(%rsp)
movslq %r14d, %rdx
movb (%rbx,%rdx), %r13b
cmpb %bpl, %r13b
jne 0xcd1c
leal 0x1(%r14), %eax
cmpl %r12d, %eax
jge 0xcdcc
leaq (%rbx,%rdx), %rcx
movslq %eax, %rdi
addq %rbx, %rdi
leal 0x2(%r14), %esi
movq %rdi, %rax
jmp 0xccd6
incq %rax
incl %esi
movzbl (%rax), %r8d
cmpl $0x20, %r8d
je 0xccd1
cmpl $0x9, %r8d
je 0xccd1
leal -0x1(%rsi), %eax
movslq %eax, %r8
movzbl (%rbx,%r8), %r8d
cmpl $0xd, %r8d
je 0xccfd
cmpl $0xa, %r8d
jne 0xcd41
cmpl %r12d, %esi
jge 0xcd3d
movslq %esi, %rcx
movzbl (%rbx,%rcx), %edx
xorl %ecx, %ecx
cmpl $0xa, %edx
je 0xcd15
cmpl $0xd, %edx
jne 0xcd3d
movl %esi, %eax
jmp 0xcda9
cmpb $0x5f, %r13b
movzbl %r13b, %eax
movl %eax, %r13d
movl $0x20, %ecx
cmovel %ecx, %r13d
cmpl $0x1, %r9d
cmovnel %eax, %r13d
movl %r14d, %eax
jmp 0xcdad
xorl %ecx, %ecx
jmp 0xcda9
cmpl %r10d, %r14d
jge 0xcd75
movsbq (%rdi), %rax
movb (%rax,%r11), %al
movb $0x1, %cl
cmpb $0x14, %al
je 0xcda6
movsbq 0x2(%rbx,%rdx), %rsi
movb (%rsi,%r11), %sil
cmpb $0x14, %sil
je 0xcda6
addq $0x2, %rdx
shlb $0x4, %al
addb %al, %sil
movl %edx, %eax
movl %esi, %r13d
jmp 0xcda9
leaq 0xaeab(%rip), %rdi      # 0x17c27
leaq 0xae91(%rip), %rsi      # 0x17c14
movl $0x116, %edx            # imm = 0x116
xorl %eax, %eax
movl %r10d, %ebp
callq 0xc960
leaq 0xad27(%rip), %r11      # 0x17ac0
movl %ebp, %r10d
movl 0x4(%rsp), %ebp
movl (%rsp), %r9d
movb $0x1, %cl
movl %r14d, %eax
testb %cl, %cl
je 0xcdb7
movslq %r15d, %rcx
movb %r13b, (%rbx,%rcx)
incl %r15d
incl %eax
movl %eax, %r14d
cmpl %r12d, %eax
jl 0xcca5
jmp 0xcdd3
xorl %r15d, %r15d
jmp 0xcdd3
movslq %r15d, %rax
movb $0x0, (%rbx,%rax)
movslq %r15d, %rax
movb $0x0, (%rbx,%rax)
cmpl $0x0, 0x2275f(%rip)     # 0x2f540
jle 0xce0b
movq %rbx, %rdi
callq 0x2110
leaq 0xae92(%rip), %rdi      # 0x17c84
leaq 0xae1b(%rip), %rsi      # 0x17c14
movl $0x13c, %edx            # imm = 0x13C
movq %rbx, %rcx
movq %rax, %r8
xorl %eax, %eax
callq 0xc960
movl %r15d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq