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

📄 ccoder.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 "cmntypes.h"   
#include "aapicmn.h"    
#include "chartype.h"   
#include "gmem.h"       
#include "cutils.h"     
#include "ccoder.h"     




typedef struct
{
    const char *str;
    CmnCharset charset; 
} CmnCharsetTable;


static const char base64[] =  
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const CmnCharsetTable charsetTable[] = 
{
    { "us-ascii",           CMN_CHARSET_US_ASCII},
    { "iso-8859-1",         CMN_CHARSET_LATIN_1},
    { "latin-1",            CMN_CHARSET_LATIN_1},
    { "utf-8",              CMN_CHARSET_UTF_8},
    { "iso-10646-ucs-2",    CMN_CHARSET_UCS_2},
    { "utf-16be",           CMN_CHARSET_UTF_16BE},
    { "utf-16le",           CMN_CHARSET_UTF_16LE},
    { "utf-16",             CMN_CHARSET_UTF_16},
    { NULL,                 CMN_CHARSET_UNKNOWN},
};












static INT8 cmnBase64DecodeChar(UINT8 ch);
static INT8 cmnHexDecodeChar(UINT8 ch);



















CMN_BOOL cmnBase64Decode( CmnClientId client, char **to, INT32 *toSize, 
    const char *from, INT32 fromSize)
{
    char b;
    INT8 cb;
    UINT8 tmp = 0;
    UINT8 savedBits = 0;
    INT32 srcPos;
    INT32 size = 0;

    *toSize = cmnBase64DecodedLength( from, fromSize);
    if (*toSize <= 0)
    {
        *to = NULL;
        return FALSE;
    } 

    *to = G_CALLOC( client, (UINT32)*toSize);
    for (srcPos = 0; srcPos < fromSize; ++srcPos) 
    { 
        b = from[srcPos];
        if (b == '=') 
        {
            break; 
        }
        else if (b == ' ' || b == '\t' || b == '\r' || b == '\n') 
        {
            continue; 
        } 
        
        
        cb = cmnBase64DecodeChar((UINT8)b);
        if (cb < 0) 
        { 
            CMN_LOG_I(("%s(%d): Illegal char %d\n", __FILE__, __LINE__, (int)b));
            G_FREE( client, *to);
            *to = NULL;
            *toSize = 0;
            return FALSE;
        } 
        
        
        if (savedBits > 0) 
        {
            (*to)[size] = (char)(tmp | ((UINT8)cb >> (savedBits - 2)));
            ++size; 
        } 

        savedBits = (UINT8)((savedBits == 0) ? 6 : savedBits - 2);
        if (savedBits > 0) 
        {
            tmp = (UINT8)(((UINT8)cb << (8 - savedBits)) & 0xff);
        } 
    } 

    *toSize = size;
    
    return TRUE;
} 











static INT8 cmnBase64DecodeChar(UINT8 ch)
{
    if (ch & 0x80)
    {
        return -1;
    }
    else if (CMN_ISUPPER(ch)) 
    {
        return (INT8)(ch - 'A');
    }
    else if (CMN_ISLOWER(ch)) 
    {
        return (INT8)(ch - 'a' + 26);
    }
    else if (CMN_ISDIGIT(ch)) 
    {
        return (INT8)(ch - '0' + 52);
    }
    else if (ch == '+') 
    {
        return 62;
    }
    else if (ch == '/') 
    {
        return 63;
    }
    else 
    {
        return -1;
    } 
} 










INT32 cmnBase64DecodedLength( const char *str, INT32 len)
{
    INT32 newLen = (len / 4) * 3;
    
    if (len > 0 && newLen > 0 && str[len - 1] == '=')
    {
        --newLen;
    } 

    if (len > 1 && newLen > 0 && str[len - 2] == '=')
    {
        --newLen;
    } 
    
    return newLen;
} 

















CMN_BOOL cmnBase64Encode( CmnClientId client, char **to, INT32 *toSize,
    const char *from, INT32 fromSize)
{
    int i;
    char *p;
    UINT8 *uFrom = (UINT8 *)from;
    CMN_BOOL isError = FALSE;

    *toSize = cmnBase64EncodedLength(fromSize);
    *to = G_CALLOC( client, (UINT32)*toSize + 1);
    p = *to;
    for (i = 0; (i + 2) < fromSize; i += 3)
    {
        if (((p + 3) - *to) > *toSize)
        {
            isError = TRUE;
            break;
        } 

        *p++ = base64[(uFrom[i] >> 2) & 0x3f];
        *p++ = base64[((uFrom[i] << 4) & 0x30) | ((uFrom[i + 1] >> 4) & 0x0f)];
        *p++ = base64[((uFrom[i + 1] << 2) & 0x3c) | ((uFrom[i + 2] >> 6) & 0x03)];
        *p++ = base64[uFrom[i + 2] & 0x3f];
    } 
    
    if (i < fromSize) 
    {
        if (((p + 3) - *to) > *toSize)
        {
            isError = TRUE;
        }
        else
        {
            *p++ = base64[(uFrom[i] >> 2) & 0x3f];
            if (i + 1 < fromSize) 
            {
                *p++ = base64[((uFrom[i] << 4) & 0x30) | ((uFrom[i + 1] >> 4) & 0x0f)];
                *p++ = base64[(uFrom[i + 1] << 2) & 0x3c];
            }
            else
            {
                *p++ = base64[(uFrom[i] << 4) & 0x30];
                *p++ = '=';
            } 

            *p++ = '=';
        } 
    } 

    if (isError || p - *to > *toSize)
    {
        CMN_LOG_I(("%s(%d): Out of bounds %d. Emergency exit.\n", 
            __FILE__, __LINE__, *toSize));
        G_FREE( client, *to);
        *to = NULL;
        *toSize = 0;
        return FALSE;
    } 

    *p = '\0'; 
    
    return TRUE;
} 







INT32 cmnBase64EncodedLength( INT32 fromSize)
{
    return (INT32)((fromSize + 2) / 3 * 4);
} 







CmnCharset cmnCharsetStr2Enum( const char *str)
{
    int i;

    for ( i = 0; charsetTable[i].str != NULL; ++i)
    {
        if (cmnStrcmpNc( str, charsetTable[i].str) == 0)
        {
            return charsetTable[i].charset;
        } 
    } 

    return CMN_CHARSET_UNKNOWN;
} 











CMN_BOOL cmnHexDecode( CmnClientId client, char **to, INT32 *toSize, 
    const char *from, INT32 fromSize)
{
    INT32 size;
    char *p;

    *to = NULL;
    *toSize = 0;
    if (fromSize % 2 != 0)
    {
        CMN_LOG_I(("%s(%d): Uneven number of bytes in 'from' string.\n", 
            __FILE__, __LINE__));
        return FALSE;
    } 

    size = fromSize / 2 + 1;
    *toSize = size;
    *to = G_CALLOC( client, (UINT32)size);
    p = *to;
    while (*from && size > 0)
    {
        if (cmnHexDecodeByte( p, from) != TRUE)
        {
            CMN_LOG_I(("%s(%d): Hex decoding failed.\n", 
                __FILE__, __LINE__));
            G_FREE( client, *to);
            *to = NULL;
            *toSize = 0;
            return FALSE;
        } 

        ++p;
        from += 2;
        --size;
    } 

    return TRUE;
} 








CMN_BOOL cmnHexDecodeByte( char *to, const char *from)
{
    INT8 low;
    INT8 high;

    high = cmnHexDecodeChar((UINT8)*from++);
    if (*from == '\0')
    {
        CMN_LOG_I(("%s(%d): Mismatch in actual strlen and in fromSize.\n", 
            __FILE__, __LINE__));
        return FALSE;
    } 

    low = cmnHexDecodeChar((UINT8)*from);
    if (high == -1 || low == -1)
    {
        CMN_LOG_I(("%s(%d): Illegal hex character in 'from' string.\n", 
            __FILE__, __LINE__));
        return FALSE;
    } 
    
    *to = (char)(((UINT8)high << 4) | low);

    return TRUE;
} 








static INT8 cmnHexDecodeChar( UINT8 ch)
{
    if (CMN_ISDIGIT(ch))
    {
        return (INT8)(ch - '0');
    }
    else if (CMN_ISUPPER(ch) && CMN_ISHEXLETTER(ch))
    {
        return (INT8)(10 + ch - 'A');
    }
    else if (CMN_ISLOWER(ch) && CMN_ISHEXLETTER(ch))
    {
        return (INT8)(10 + ch - 'a');
    }
    else
    {
        return -1;
    } 
} 













CMN_BOOL cmnQuotedPrintableDecode( CmnClientId client, char **to, INT32 *toSize, 
    const char *from)
{
    char hex;
    char *offset;
    
    *toSize = cmnQuotedPrintableDecodedLength(from);
    if (*toSize <= 0)
    {
        CMN_LOG_I(("%s(%d): Length is %ld\n", __FILE__, __LINE__, *toSize));
        *to = NULL;
        *toSize = 0;
        return TRUE;
    } 

    *to = G_CALLOC( client, (UINT32)*toSize);
    offset = *to;
    while (*from)
    {
        switch (*from)
        {
        case '=':
            ++from;      
            
            
            if (*from == '\r')
            {
                if (*(from + 1) == '\n')
                {
                    ++from;
                } 
                continue;
            } 
            
            
            if ( cmnHexDecodeByte( &hex, from) != TRUE)
            {
                CMN_LOG_I(("%s(%d): Couldn't hexDecode %d, %d\n", 
                    __FILE__, __LINE__, from, *from));
                G_FREE( client, *to);
                *to = NULL;
                return FALSE;
            } 

            
            *offset++ = hex;

            ++from;     
            break;
        default:
            
            *offset++ = *from;
            break;
        } 

        ++from;      
    } 
    
    return TRUE;
} 







INT32 cmnQuotedPrintableDecodedLength( const char *buf)
{
    INT32 size = 0;
    
    while (*buf)
    {
        if (*buf == '=')
        {
            ++buf;      
            
            
            if (*buf == '\r')
            {
                if (*(buf + 1) == '\n')
                {
                    ++buf;
                } 
                continue;
            }
            else if (*buf == '\0')
            {
                break;
            } 
            
            ++buf;   
        } 

        ++size;
        ++buf;      
    } 

    return ++size; 
} 

⌨️ 快捷键说明

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