⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crfc2047.c

📁 彩信MMS的全部代码
💻 C
字号:
/*
 * Copyright (C) Obigo AB, 2002-2005.
 * All rights reserved.
 *
 * This software is covered by the license agreement between
 * the end user and Obigo AB, and may be 
 * used and copied only in accordance with the terms of the 
 * said agreement.
 *
 * Obigo AB assumes no responsibility or 
 * liability for any errors or inaccuracies in this software, 
 * or any consequential, incidental or indirect damage arising
 * out of the use of the software.
 *
 */















































#include "cansilib.h"   
#include "cmnconf.h"    

#include "codecvt.h"    

#include "cmntypes.h"   
#include "aapicmn.h"    
#include "gmem.h"       
#include "chartype.h"   
#include "crfc2047.h"   
#include "ccoder.h"     


#define RFC2047_BEGIN   "=?UTF-8?"
#define RFC2047_BASE64  "B?"
#define RFC2047_END     "?="




#define CMN_CHAR_CONV_TYPE      codecvt_convert_t

#define CMN_CHAR_CONV_FUNC_FIND codecvt_find_function
















static INT32 cmnCharsetDecodedTextLength( char *charset, const char *from, 
    INT32 fromLen);
static CMN_BOOL cmnCharsetDecodeText( char *charset, char *to, INT32 *toLen,
    const char *from, INT32 fromLen);
static CMN_BOOL cmnDecodeText( CmnClientId client, char encoding, 
    char **to, INT32 *toLen, const char *from, INT32 fromLen);
static void cmnRfc2047LocateTags( char *from, char **charset, char *encoding, 
    char **encodedText);











static INT32 cmnCharsetDecodedTextLength( char *charset, const char *from, 
    INT32 fromLen)
{
    INT32 length = -1;

    if (cmnCharsetDecodeText( charset, NULL, &length, from, fromLen) == FALSE)
    {
        CMN_LOG_I(("%s(%d): Couldn't determine length\n", __FILE__, __LINE__));
        length = -1;
    } 

    return length;
} 











static CMN_BOOL cmnCharsetDecodeText( char *charset, char *to, INT32 *toLen, 
    const char *from, INT32 fromLen)
{
    int mibEnum = -1;
    int ret = 0;
    int iDestLen = (int)*toLen;
    int iSrcLen = (int)fromLen;
    char *p = charset;
    CMN_CHAR_CONV_TYPE *cvtFunction = NULL;

    
    while (*p)
    {
        *p = (char)CMN_TOLOWER(*p);
        ++p;
    } 
    
    
    mibEnum = cmnCharsetStr2Enum(charset);
    if (mibEnum == CMN_CHARSET_UNKNOWN)
    {
        

        mibEnum = CHARSET_LATIN_1;
    } 
    
    
    if (mibEnum == CHARSET_UTF_8)
    {
        if (to)
        {
            memcpy( to, from, (UINT32)fromLen);
            to[fromLen] = 0x00;
        } 

        *toLen = fromLen;
        return TRUE;
    }
    else
    {
        cvtFunction = CMN_CHAR_CONV_FUNC_FIND( mibEnum, CMN_CHARSET_UTF_8);
        if (cvtFunction == NULL)
        {   
            CMN_LOG_I(("%s(%d): Unknown encoding %d\n", 
                __FILE__, __LINE__, mibEnum));
            return FALSE;
        } 
        
        ret = cvtFunction( from, &iSrcLen, to, &iDestLen);
        *toLen = (INT32)iDestLen;
        
        return ret == 0;
    } 
} 












static CMN_BOOL cmnDecodeText( CmnClientId client, char encoding, 
    char **to, INT32 *toLen, const char *from, INT32 fromLen)
{
    CMN_BOOL retVal = FALSE;
    
    switch (encoding)
    {
    case 'b':
    case 'B': 
        retVal = cmnBase64Decode( client, to, toLen, from, fromLen);
        break;
    case 'q':
    case 'Q': 
        retVal = cmnQuotedPrintableDecode( client, to, toLen, from);
        break;
    default:
        CMN_LOG_I(("%s(%d): Unknown encoding %d\n", __FILE__, __LINE__, encoding));
        retVal = FALSE;
        break;
    } 
    
    return retVal;
} 













static void cmnRfc2047LocateTags( char *str, char **charset, char *encoding, 
    char **encodedText)
{
    if (cmnRfc2047IsEncoded(str) != TRUE)
    {
        CMN_LOG_I(("%s(%d): %s isn't RFC 2047 encoded\n", __FILE__, __LINE__, str));
        return;
    } 

    
    str += 2;
    
    
    *charset = str;
    
    
    while (*str != '?')
    {
        ++str;
    } 

    
    *str = '\0';
    ++str;
    
    
    *encoding = *str;
    
    
    str += 2;
    
    
    *encodedText = str;
    
    
    while (str[0] != '\0')
    {
        if (str[0] == '?' && str[1] == '=')
        {
            
            *str = '\0';
            return;
        } 

        ++str;
    } 
} 















CMN_BOOL cmnRfc2047Decode( CmnClientId client, char **to, INT32 *toSize, 
    const char *from, INT32 fromLen)
{
    CMN_BOOL retVal = FALSE;
    char *fromCopy = NULL;
    char *charset = NULL;
    char encoding = 0x00;
    char *encodedText = NULL;
    INT32 decodedLen = 0;       
    UINT32 textLen;
    char *decodedText;

    if (cmnRfc2047IsEncoded(from) == FALSE)
    {
        CMN_LOG_I(("%s(%d): %s isn't RFC 2047 encoded\n", 
            __FILE__, __LINE__, from));
        return FALSE;
    } 

    fromCopy = G_CALLOC( client, (UINT32)(fromLen + 1));
    if (fromCopy)
    {
        memcpy( fromCopy, from, (UINT32)(fromLen + 1));
        cmnRfc2047LocateTags( fromCopy, &charset, &encoding, &encodedText);
        
        
        textLen = strlen(encodedText);

        
        if (cmnDecodeText( client, encoding, &decodedText, 
            &decodedLen, encodedText, (INT32)textLen))
        {
            
            *toSize = cmnCharsetDecodedTextLength( charset, decodedText, 
                decodedLen) + 1;

            if (to != NULL)
            {
                *to = G_CALLOC( client, (UINT32)*toSize);
                
                retVal = cmnCharsetDecodeText( charset, *to, toSize, 
                    decodedText, decodedLen);
                if (retVal != TRUE)
                {
                    CMN_LOG_I(("%s(%d): charset decoding failed\n", 
                        __FILE__, __LINE__));
                    G_FREE( client, *to);
                    *to = NULL;
                    *toSize = 0;
                } 
            } 

            G_FREE( client, decodedText);
        } 
        
        G_FREE( client, fromCopy);
    } 
    
    return retVal;
} 










INT32 cmnRfc2047DecodedLength( const char *src)
{
    INT32 destSize = 0;

    if (cmnRfc2047Decode( 0, NULL, &destSize, src, (INT32)strlen(src)) == FALSE)
    {
        return -1;
    } 

    return (INT32)destSize;
} 












CMN_BOOL cmnRfc2047Encode( CmnClientId client, char **to, const char *from)
{
    INT32 toSize;
    INT32 destLen;
    INT32 srcLen = (INT32)strlen(from);
    char *tmp;

    destLen = cmnBase64EncodedLength(srcLen) + (INT32)strlen(RFC2047_BEGIN) +
        (INT32)strlen(RFC2047_BASE64) + (INT32)strlen(RFC2047_END) + 1; 
    *to = G_CALLOC( client, (UINT32)destLen);
    
    
    strcpy( *to, RFC2047_BEGIN);
    strcat( *to, RFC2047_BASE64);
    if (cmnBase64Encode( client, &tmp, &toSize, from, srcLen) == FALSE)
    {
        CMN_LOG_I(("%s(%d): Base64 encoding failed\n", __FILE__, __LINE__));
        G_FREE( client, *to);
        *to = NULL;
        return FALSE;
    } 

    strcat( *to, tmp);
    strcat( *to, RFC2047_END);

    G_FREE( client, tmp);
    return TRUE;
} 












CMN_BOOL cmnRfc2047IsEncoded( const char *str)
{
    UINT32 strLen = strlen(str);
    
    
    if (strLen < 7)
    {
        CMN_LOG_I(("%s(%d): RFC 2047 string is too short %d\n", 
            __FILE__, __LINE__, (int)strLen));
        return FALSE;
    } 
    
    
    if (str[0] != '=' || str[1] != '?')
    {
        CMN_LOG_I(("%s(%d): RFC 2047 start is wrong %d, %d\n", 
            __FILE__, __LINE__, (int)str[0], (int)str[1]));
        return FALSE;
    } 
    
    str += 2;  
    
    
    while (*str && *str != '?')   
    {
        ++str;
    } 

    
    if (*str == 0x00)
    {
        return FALSE;
    } 

    
    ++str;
    
    
    
    if (str[0] == 0x00 || str[0] == '?' || 
        str[1] == 0x00 || str[1] != '?')
    {
        return FALSE;
    } 
    
    
    str += 2;
    
    
    while (str[0] != '\0')
    {
        if (str[0] == '?' && str[1] == '=')
        {
            
            return TRUE;
        } 

        ++str;
    } 

    
    return FALSE;
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -