// File: /workspace/github_c_makefile_star2_O2/inflex[P]ripMIME/libmime-decoders.c
// Function: MDECODE_decode_ISO
int MDECODE_decode_ISO( char *isostring, int size )
{
    char *start_pair, *end_pair;
    char *iso, *iso_copy;
    char encoding_type='-';
    char encoding_charset[ MDECODE_ISO_CHARSET_SIZE_MAX ];
    char *iso_start, *iso_end;
    int iso_decoded;

    DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: ISO-string='%s'",FL,isostring);

    // Process of decoding the ISO encoded string sequence.
    //  ( this process is repeated until we run out of ISO sequences )
    //
    //  1. Check that the string has a =? sequence within it ( indicates the start of the ISO encoding
    //  2. tokenise the sequence succeeding the =? token into its three (3) parts, namely the code-page, encoding-type and string respectively
    //  3. decode the string based on the encoding type, Q = Quoted-Printable, B = BASE64
    //

    iso_end = iso_start = NULL;
    start_pair = end_pair = NULL;
    iso_copy = malloc( sizeof(char) *( size +1 ) );
    do {
        iso_decoded = 0;
        start_pair = strstr( isostring, "=?" );
//      if ( start_pair ) end_pair   = strstr( start_pair +2, "?=" );
        if (( start_pair != NULL ))
        {
            iso_start = start_pair;
            // There's probably a better way of doing this, but, for us to find the end of this
            //  particular 'ISO' sequence, we need to hop past 3 more ?'s ( assuming we've already
            //  found the first one.
            DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: ISO start = %s",FL,iso_start);

            iso_end = strchr( iso_start +strlen("=?"), '?' ); // Jump past the encoding
            if (iso_end) iso_end = strchr( iso_end +1, '?' ); // Jump past the Q or B
            if (iso_end) iso_end = strpbrk( iso_end +1, "?\n\r\t;" );  // dropped the SPACE here.
            if ((iso_end != NULL)&&(*iso_end == '?')) iso_end+=2;

            if ( (iso_start) && (iso_end) )
            {
                char *token_end;
                char restore_char='\0';

                // Copy the Encoding page/code.
                iso = iso_start +strlen("=?");

                token_end = strchr(iso,'?');
                if (token_end) *token_end = '\0';
                snprintf( encoding_charset, sizeof( encoding_charset ), "%s", iso);
                DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: ISO char set = '%s'",FL,encoding_charset);

                iso = token_end +1;

                // Get the encoding _type_ (BASE64/QuotedPrintable etc)
                token_end = strchr(iso,'?');
                encoding_type = *iso;

                iso = token_end +1;

                DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: ISO encoding char = '%c'",FL,encoding_type);

                // Get the encoded string
                token_end = strpbrk(iso,"?;\n\r"); //DROPPED THE SPACE here
                // When unfolding, WSP should be ignored. (https://tools.ietf.org/html/rfc5322#section-2.2.3)
                // WSP =  SP / HTAB ; white space (https://tools.ietf.org/html/rfc5234#appendix-B.1)
                if (token_end != NULL)
                {
                    if ((*token_end != '?')&&(*token_end != ';'))
                    {
                        restore_char = *token_end;
                    }
                    *token_end = '\0';
                }

                if (iso)
                {
                    DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: Encoded String = '%s'\n", FL, iso );
                    switch ( encoding_type ) {

                        case MDECODE_ISO_ENCODING_Q:
                        case MDECODE_ISO_ENCODING_q:
                            DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: Decoding filename using Quoted-Printable (%s)\n", FL, iso);
                            MDECODE_decode_qp_ISO(iso);
                            iso_decoded = 1;
                            break;

                        case MDECODE_ISO_ENCODING_B:
                        case MDECODE_ISO_ENCODING_b:
                            DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: Decoding filename using BASE64 (%s)\n", FL, iso);
                            MDECODE_decode_short64( iso );
                            iso_decoded = 1;
                            break;

                        default:
                            if (glb.verbose) LOGGER_log("%s:%d:MDECODE_decode_ISO:ERROR: The encoding character '%c' is not a valid type of encoding\n", FL, encoding_type );
                    }

                    // If we decoded the string okay, then we need to recompose the string
                    if ( iso_decoded == 1 )
                    {
                        char *new_end_pos;
                        DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: Decoded String = '%s'\n", FL, iso );
                        *iso_start = '\0'; // Terminate the original string before the start of the ISO data

                        // Because sometimes ISO strings are broken over multiple lines
                        //      due to wrapping requirements of RFC(2)822, we need to
                        //      sniff out these tab or spaces and crop them out of our
                        //      final ISO string.  We cannot simply search for the next
                        //      =? sequence using strstr() because it might traverse
                        //      beyond the end of the current 'line' (ie, \r\n termination)

                        if (token_end)
                        {
                            iso_end = token_end +1;
                            DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: iso_end = '%20s'",FL, iso_end);
                            while ((*iso_end == '?')||(*iso_end == '=')) iso_end++;
                            DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: iso_end = '%20s'",FL, iso_end);
                            new_end_pos = iso_end;
                            while ((*new_end_pos == ' ')||(*new_end_pos == '\t')) new_end_pos++;
                            if (strncmp(new_end_pos,"=?",2)==0) iso_end = new_end_pos;
                        } else {
                            iso_end = NULL;
                        }

                        DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: ISO-END = '%20s'",FL,iso_end);

                        /** We now have the string split into 3 peices,
                          **    isostring = pointing to the start
                          **    iso = newly decoded string
                          **    iso_end = start of string after the non-decoded ISO portion
                          **/

                        /** Generate new string using the decoded ISO to a temporary string **/
                        if (restore_char != '\0')
                        {
                            DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: Recomposing string with restore-char of '%c'",FL,restore_char);
                            DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: ISO-end (start of end of string) is \n%s",FL,iso_end);
                            snprintf( iso_copy, size, "%s%s%c%s", isostring, iso, restore_char, (iso_end?iso_end:"") );
                        } else {
                            DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: Recomposing string with NO restore-char",FL,restore_char);
                            snprintf( iso_copy, size, "%s%s%s", isostring, iso, (iso_end?iso_end:"") );
                        }

                        /** Switch the new headers over to the original headers again **/
                        snprintf( isostring, size, "%s", iso_copy );
                        DMD LOGGER_log("%s:%d:MDECODE_decode_ISO:DEBUG: New ISO string = \n%s",FL,isostring);
                    }
                }
            }

        } // if (iso_start)
    }
    while (iso_decoded == 1 );
    if (iso_copy) free(iso_copy);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %esi, %r14d
movq %rdi, %rbx
cmpl $0x0, 0x21e20(%rip)     # 0x2e540
jle 0xc73f
leaq 0xa57d(%rip), %rdi      # 0x16ca6
leaq 0xa514(%rip), %rsi      # 0x16c44
movl $0x16e, %edx            # imm = 0x16E
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc2a1
leal 0x1(%r14), %eax
movslq %eax, %rdi
callq 0x22a0
movq %rax, 0x8(%rsp)
movslq %r14d, %rbp
movq %rbp, 0x10(%rsp)
movq %rbx, %rdi
leaq 0xa574(%rip), %rsi      # 0x16cd6
callq 0x23d0
testq %rax, %rax
je 0xcb81
movq %rax, %r15
movq %rax, %r14
cmpl $0x0, 0x21dc3(%rip)     # 0x2e540
jle 0xc79c
leaq 0xa553(%rip), %rdi      # 0x16cd9
leaq 0xa4b7(%rip), %rsi      # 0x16c44
movl $0x185, %edx            # imm = 0x185
movq %r14, %rcx
xorl %eax, %eax
callq 0xc2a1
addq $0x2, %r15
movq %r15, %rdi
pushq $0x3f
popq %rsi
callq 0x2120
testq %rax, %rax
je 0xcb81
movq %rax, %r12
leaq 0x1(%rax), %r13
movq %r13, %rdi
pushq $0x3f
popq %rsi
callq 0x2120
testq %rax, %rax
je 0xcb81
incq %rax
movq %rax, %rdi
leaq 0xa52c(%rip), %rsi      # 0x16d08
callq 0x2300
testq %rax, %rax
je 0xcb81
movq %r14, 0x18(%rsp)
movq %rbx, %r14
movb $0x0, (%r12)
xorl %ebx, %ebx
leaq 0x20(%rsp), %r12
movq %r12, %rdi
pushq $0x10
popq %rsi
leaq 0xa855(%rip), %rdx      # 0x17060
movq %r15, %rcx
xorl %eax, %eax
callq 0x2140
cmpl $0x0, 0x21d24(%rip)     # 0x2e540
jle 0xc845
leaq 0xa4e9(%rip), %rdi      # 0x16d0e
leaq 0xa418(%rip), %rsi      # 0x16c44
movl $0x197, %edx            # imm = 0x197
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
cmpl $0x0, 0x21cfe(%rip)     # 0x2e540
setg %bl
movq %r13, %rdi
pushq $0x3f
popq %rsi
callq 0x2120
movq %rax, %r12
movsbl (%r13), %ebp
testb %bl, %bl
je 0xc878
leaq 0xa4df(%rip), %rdi      # 0x16d42
leaq 0xa3da(%rip), %rsi      # 0x16c44
movl $0x1a1, %edx            # imm = 0x1A1
movl %ebp, %ecx
xorl %eax, %eax
callq 0xc2a1
incq %r12
movq %r12, %rdi
leaq 0xa4f6(%rip), %rsi      # 0x16d7b
callq 0x2300
movq %rax, %r13
testq %rax, %rax
je 0xc8af
movzbl (%r13), %eax
xorl %r15d, %r15d
movl %eax, %ecx
orl $0x4, %ecx
cmpl $0x3f, %ecx
je 0xc8a8
movsbl %al, %r15d
movb $0x0, (%r13)
jmp 0xc8b2
xorl %r15d, %r15d
cmpl $0x0, 0x21c87(%rip)     # 0x2e540
jle 0xc8d8
leaq 0xa4be(%rip), %rdi      # 0x16d80
leaq 0xa37b(%rip), %rsi      # 0x16c44
movl $0x1b2, %edx            # imm = 0x1B2
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
cmpb $0x42, %bpl
je 0xc925
movzbl %bpl, %eax
cmpl $0x71, %eax
je 0xc8f5
cmpl $0x62, %eax
je 0xc925
cmpl $0x51, %eax
jne 0xcb5c
cmpl $0x0, 0x21c44(%rip)     # 0x2e540
jle 0xc91b
leaq 0xa4b2(%rip), %rdi      # 0x16db7
leaq 0xa338(%rip), %rsi      # 0x16c44
movl $0x1b7, %edx            # imm = 0x1B7
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
movq %r12, %rdi
callq 0xc6f1
jmp 0xc953
cmpl $0x0, 0x21c14(%rip)     # 0x2e540
jle 0xc94b
leaq 0xa4d1(%rip), %rdi      # 0x16e06
leaq 0xa308(%rip), %rsi      # 0x16c44
movl $0x1be, %edx            # imm = 0x1BE
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
movq %r12, %rdi
callq 0xc481
movq %r14, %rbx
movq 0x8(%rsp), %r14
movq 0x10(%rsp), %rbp
movl 0x21bda(%rip), %eax     # 0x2e540
testl %eax, %eax
jle 0xc98d
leaq 0xa537(%rip), %rdi      # 0x16ea8
leaq 0xa2cc(%rip), %rsi      # 0x16c44
movl $0x1cb, %edx            # imm = 0x1CB
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
movl 0x21bb3(%rip), %eax     # 0x2e540
movq 0x18(%rsp), %rcx
movb $0x0, (%rcx)
testq %r13, %r13
je 0xca24
incq %r13
testl %eax, %eax
jle 0xc9c7
leaq 0xa533(%rip), %rdi      # 0x16edf
leaq 0xa291(%rip), %rsi      # 0x16c44
movl $0x1d8, %edx            # imm = 0x1D8
movq %r13, %rcx
xorl %eax, %eax
callq 0xc2a1
jmp 0xc9c7
incq %r13
movzbl (%r13), %eax
orl $0x2, %eax
cmpl $0x3f, %eax
je 0xc9c4
cmpl $0x0, 0x21b65(%rip)     # 0x2e540
jle 0xc9fa
leaq 0xa4fb(%rip), %rdi      # 0x16edf
leaq 0xa259(%rip), %rsi      # 0x16c44
movl $0x1da, %edx            # imm = 0x1DA
movq %r13, %rcx
xorl %eax, %eax
callq 0xc2a1
movq %r13, %rax
movzbl (%rax), %ecx
cmpl $0x9, %ecx
je 0xca0a
cmpl $0x20, %ecx
jne 0xca0f
incq %rax
jmp 0xc9fd
cmpl $0x3d, %ecx
jne 0xca1c
cmpb $0x3f, 0x1(%rax)
cmoveq %rax, %r13
movl 0x21b1e(%rip), %eax     # 0x2e540
jmp 0xca27
xorl %r13d, %r13d
testl %eax, %eax
jle 0xca48
leaq 0xa4de(%rip), %rdi      # 0x16f10
leaq 0xa20b(%rip), %rsi      # 0x16c44
movl $0x1e2, %edx            # imm = 0x1E2
movq %r13, %rcx
xorl %eax, %eax
callq 0xc2a1
movl 0x21af2(%rip), %eax     # 0x2e540
testl %r15d, %r15d
je 0xcacb
testl %eax, %eax
jle 0xca9a
leaq 0xa4e3(%rip), %rdi      # 0x16f41
leaq 0xa1df(%rip), %rsi      # 0x16c44
movl $0x1ed, %edx            # imm = 0x1ED
movl %r15d, %ecx
xorl %eax, %eax
callq 0xc2a1
cmpl $0x0, 0x21ac5(%rip)     # 0x2e540
jle 0xca9a
leaq 0xa50a(%rip), %rdi      # 0x16f8e
leaq 0xa1b9(%rip), %rsi      # 0x16c44
movl $0x1ee, %edx            # imm = 0x1EE
movq %r13, %rcx
xorl %eax, %eax
callq 0xc2a1
testq %r13, %r13
leaq 0x8826(%rip), %rax      # 0x152ca
cmoveq %rax, %r13
movq %r13, (%rsp)
movq %r14, %rdi
movq %rbp, %rsi
leaq 0xa51d(%rip), %rdx      # 0x16fd6
movq %rbx, %rcx
movq %r12, %r8
movl %r15d, %r9d
xorl %eax, %eax
callq 0x2140
jmp 0xcb16
testl %eax, %eax
jle 0xcaeb
leaq 0xa509(%rip), %rdi      # 0x16fdf
leaq 0xa167(%rip), %rsi      # 0x16c44
movl $0x1f1, %edx            # imm = 0x1F1
xorl %ecx, %ecx
xorl %eax, %eax
callq 0xc2a1
testq %r13, %r13
leaq 0x87d5(%rip), %rax      # 0x152ca
cmoveq %rax, %r13
movq %r14, %rdi
movq %rbp, %rsi
leaq 0xa521(%rip), %rdx      # 0x17027
movq %rbx, %rcx
movq %r12, %r8
movq %r13, %r9
xorl %eax, %eax
callq 0x2140
movq %rbx, %rdi
movq %rbp, %rsi
leaq 0xa53d(%rip), %rdx      # 0x17060
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
cmpl $0x0, 0x21a0c(%rip)     # 0x2e540
jle 0xc758
leaq 0xa4ed(%rip), %rdi      # 0x1702e
leaq 0xa0fc(%rip), %rsi      # 0x16c44
movl $0x1f7, %edx            # imm = 0x1F7
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc2a1
jmp 0xc758
cmpl $0x0, 0x219e1(%rip)     # 0x2e544
je 0xcb81
leaq 0xa2df(%rip), %rdi      # 0x16e4b
leaq 0xa0d1(%rip), %rsi      # 0x16c44
movl $0x1c4, %edx            # imm = 0x1C4
movl %ebp, %ecx
xorl %eax, %eax
callq 0xc2a1
movq 0x8(%rsp), %rdi
callq 0x2030
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq