PRIVATE char *intlmime_encode_qp_buf(char *subject)
{
    char *output = 0;
    unsigned char *p, *pDest ;
    int i, n, len ;

    if (subject == NULL || *subject == '\0')
        return NULL;
    len = strlen(subject);
    output = XP_ALLOC(len * 3 + 1);
    if (output == NULL)
        return NULL;

    p = (unsigned char*)subject;
    pDest = (unsigned char*)output ;

    for (i = 0; i < len; i++)
    {
        /* XP_IS_ALPHA(*p) || XP_IS_DIGIT(*p)) */
        if ((*p < 0x80) &&
            (((*p >= 'a') && (*p <= 'z')) ||
             ((*p >= 'A') && (*p <= 'Z')) ||
             ((*p >= '0') && (*p <= '9')))
           )
            *pDest = *p;
        else
        {
            *pDest++ = '=';
            n = (*p & 0xF0) >> 4; /* high byte */
            if (n < 10)
                *pDest = '0' + n;
            else
                *pDest = 'A' + n - 10;
            pDest ++ ;

            n = *p & 0x0F;          /* low byte */
            if (n < 10)
                *pDest = '0' + n;
            else
                *pDest = 'A' + n - 10;
        }

        p ++;
        pDest ++;
    }

    *pDest = '\0';
    return output;
}