시작단계. Mers 가 이미지로 발라 놓은 코드 따라 치기


static unsigned long convert(wchar_t ch)

{

    unsigned long ret;

    if( ch > 0x7F )

    {

        if( ch > 0x7FF )

        {

            if( ch > 0xFFFF )

            {

                ret = ( ch >> 18 ) | 0xF0;

                ret <<= 8;

                ret |= ( ( ch >> 12 ) & 0x3F ) | 0x80;

                ret <<= 8;

                ret |= ( ( ch >> 6 ) & 0x3F ) | 0x80;

                ret <<= 8;

                ret |= ( ch & 0x3F ) | 0x80;

            }

            else

            {

                ret = ( ch >> 12 ) | 0xE0;

                ret <<= 8;

                ret |= ( ( ch >> 6 ) & 0x3F ) | 0x80;

                ret <<= 8;

                ret |= ( ch & 0x3F ) | 0x80;

            }

        }

        else

        {

            ret = ( ch >> 6 ) | 0xC0;

            ret <<= 8;

            ret |= ( ch & 0x3F ) | 0x80;

        }

    }

    else ret = ch;

    return ret;

}


1단계. 각 케이스별 상수 OR 연산을 모아본 후, 쉬프트와 & 연산을 합친다. 


static unsigned long convert_1( wchar_t ch )

{

    unsigned long ret;

    if( ch > 0xFFFF )

    {

        ret = ( ( ch << 6 ) & 0x3F000000 ) |

              ( ( ch << 4 ) & 0x003F0000 ) |

              ( ( ch << 2 ) & 0x00003F00 ) |

              ( ( ch << 0 ) & 0x0000003F ) |

              0xF0808080;

    }

    else if ( ch > 0x7FF )

    {

        ret = ( ( ch << 4 ) & 0x003F0000 ) |

              ( ( ch << 2 ) & 0x00003F00 ) |

              ( ( ch << 0 ) & 0x0000003F ) |

              0x00E08080;

    }

    else if ( ch > 0x7F )

    {

        ret = ( ( ch << 2 ) & 0x00003F00 ) |

              ( ( ch << 0 ) & 0x0000003F ) |

              0x0000C080;

    }

    else ret = ch;

    return ret;

}



2단계. 공통 코드를 한 단계씩 앞으로 빼 내자. (ㅅㅅㅅ 한테 잔소리 들을것 같으니까 괄호도 빼자)


static unsigned long to_utf8( wchar_t ch )

{

    if( ch < 0x80 ) return ch;

    unsigned long ret = ch & 0x3F | ch << 2 & 0x3F00;

    if( ch < 0x800 ) return ret | 0xC080;

    ret |= ch << 4 & 0x3F0000;

    if( ch < 0x10000 ) return ret | 0xE08080;

    return ret | ch << 6 & 0x3F000000 | 0xF0808080;

}


낄낄.