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

📄 util.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

util.cpp

Abstract:


Notes:


--*/


#include "precomp.h"

#ifdef assert
#undef assert
#endif
#include <Safeint.hxx>

#ifdef RIL_RADIO_RESILIENCE
#include <wincrypt.h>
#endif // RIL_RADIO_RESILIENCE

#ifndef _PREFAST_
#pragma warning( disable: 4068 )
#endif

//
// Table used to convert from GSM default alphabet to Unicode
//
static const WCHAR g_rgwchGSMToUnicode[128] =
{
    L'@',   0x00a3, L'$',   0x00a5, 0x00e8, 0x00e9, 0x00f9, 0x00ec, // 0x00 - 0x07
    0x00f2, 0x00c7, L'\n',  0x00d8, 0x00f8,  L'\r', 0x00c5, 0x00e5, // 0x08 - 0x0f
    0x0394, L'_',   0x03a6, 0x0393, 0x039b, 0x03a9, 0x03a0, 0x03a8, // 0x10 - 0x17
    0x03a3, 0x0398, 0x039e, L' ',   0x00c6, 0x00e6, 0x00df, 0x00c9, // 0x18 - 0x1f
    L' ',   L'!',   L'"',   L'#',   0x00a4, L'%',   L'&',   L'\'',  // 0x20 - 0x27
    L'(',   L')',   L'*',   L'+',   L',',   L'-',   L'.',   L'/',   // 0x28 - 0x2f
    L'0',   L'1',   L'2',   L'3',   L'4',   L'5',   L'6',   L'7',   // 0x30 - 0x37
    L'8',   L'9',   L':',   L';',   L'<',   L'=',   L'>',   L'?',   // 0x38 - 0x3f
    0x00a1, L'A',   L'B',   L'C',   L'D',   L'E',   L'F',   L'G',   // 0x40 - 0x47
    L'H',   L'I',   L'J',   L'K',   L'L',   L'M',   L'N',   L'O',   // 0x48 - 0x4f
    L'P',   L'Q',   L'R',   L'S',   L'T',   L'U',   L'V',   L'W',   // 0x50 - 0x57
    L'X',   L'Y',   L'Z',   0x00c4, 0x00d6, 0x00d1, 0x00dc, 0x00a7, // 0x58 - 0x5f
    0x00bf, L'a',   L'b',   L'c',   L'd',   L'e',   L'f',   L'g',   // 0x60 - 0x67
    L'h',   L'i',   L'j',   L'k',   L'l',   L'm',   L'n',   L'o',   // 0x68 - 0x6f
    L'p',   L'q',   L'r',   L's',   L't',   L'u',   L'v',   L'w',   // 0x70 - 0x77
    L'x',   L'y',   L'z',   0x00e4, 0x00f6, 0x00f1, 0x00fc, 0x00e0, // 0x78 - 0x7f
};


//
// Table used to convert from Unicode to GSM default alphabet
//
static const CHARMAP g_rgcmUnicodeToGSMExceptions[] =
{
    { 0x02, L'$'}, { 0x00, L'@'}, { 0x11, L'_'}, { 0x40, 0x00a1},
    { 0x01, 0x00a3}, { 0x24, 0x00a4}, { 0x03, 0x00a5}, { 0x5f, 0x00a7},
    { 0x60, 0x00bf}, { 0x41, 0x00c0}, { 0x41, 0x00c1}, { 0x41, 0x00c2},
    { 0x41, 0x00c3}, { 0x5b, 0x00c4}, { 0x0e, 0x00c5}, { 0x1c, 0x00c6},
    { 0x09, 0x00c7}, { 0x45, 0x00c8}, { 0x1f, 0x00c9}, { 0x45, 0x00ca},
    { 0x45, 0x00cb}, { 0x49, 0x00cc}, { 0x49, 0x00cd}, { 0x49, 0x00ce},
    { 0x49, 0x00cf}, { 0x5d, 0x00d1}, { 0x4f, 0x00d2}, { 0x4f, 0x00d3},
    { 0x4f, 0x00d4}, { 0x4f, 0x00d5}, { 0x5c, 0x00d6}, { 0x0b, 0x00d8},
    { 0x55, 0x00d9}, { 0x55, 0x00da}, { 0x55, 0x00db}, { 0x5e, 0x00dc},
    { 0x59, 0x00dd}, { 0x1e, 0x00df}, { 0x7f, 0x00e0}, { 0x61, 0x00e1},
    { 0x61, 0x00e2}, { 0x61, 0x00e3}, { 0x7b, 0x00e4}, { 0x0f, 0x00e5},
    { 0x1d, 0x00e6}, { 0x09, 0x00e7}, { 0x04, 0x00e8}, { 0x05, 0x00e9},
    { 0x65, 0x00ea}, { 0x65, 0x00eb}, { 0x07, 0x00ec}, { 0x69, 0x00ed},
    { 0x69, 0x00ee}, { 0x69, 0x00ef}, { 0x7d, 0x00f1}, { 0x08, 0x00f2},
    { 0x6f, 0x00f3}, { 0x6f, 0x00f4}, { 0x6f, 0x00f5}, { 0x7c, 0x00f6},
    { 0x0c, 0x00f8}, { 0x06, 0x00f9}, { 0x75, 0x00fa}, { 0x75, 0x00fb},
    { 0x7e, 0x00fc}, { 0x79, 0x00fd}, { 0x79, 0x00ff}, { 0x13, 0x0393},
    { 0x10, 0x0394}, { 0x19, 0x0398}, { 0x14, 0x039b}, { 0x1a, 0x039e},
    { 0x16, 0x03a0}, { 0x18, 0x03a3}, { 0x12, 0x03a6}, { 0x17, 0x03a8},
    { 0x15, 0x03a9},
};
#define NUM_EXCEPTIONS  (sizeof(g_rgcmUnicodeToGSMExceptions) / sizeof(CHARMAP))


//
// Table used to map semi-byte values to hex characters
//
static const char g_rgchSemiByteToCharMap[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};



//
// Convert a semi-byte into its character representation
//
char SemiByteToChar(const BYTE bByte, const BOOL fHigh)
{
    BYTE bSemiByte = (fHigh ? (bByte & 0xf0) >> 4 : bByte & 0x0f);
    DEBUGCHK(0x10 > bSemiByte);
    return g_rgchSemiByteToCharMap[bSemiByte];
}


//
// Combine 2 characters representing semi-bytes into a byte
//
BYTE SemiByteCharsToByte(const char chHigh, const char chLow)
{
    BYTE bRet;

    if ('0' <= chHigh && '9' >= chHigh)
    {
        bRet = (chHigh - '0') << 4;
    }
    else
    {
        bRet = (0x0a + chHigh - 'A') << 4;
    }

    if ('0' <= chLow && '9' >= chLow)
    {
        bRet |= (chLow - '0');
    }
    else
    {
        bRet |= (0x0a + chLow - 'A');
    }
    return bRet;
}


//
// Comparison routine used for binary search below
//
static int _cdecl BSCompareChars(const void* pElem1, const void* pElem2)
{
    WCHAR wch1 = ((CHARMAP*)pElem1)->wch;
    WCHAR wch2 = ((CHARMAP*)pElem2)->wch;
    int iRet;

    if (wch1 < wch2)
    {
        iRet = -1;
    }
    else if (wch1 == wch2)
    {
        iRet = 0;
    }
    else
    {
        iRet = 1;
    }
    return iRet;
}


//
// Convert a single Unicode character to GSM default alphabet
//
BOOL UnicodeCharToGSM(const WCHAR wch, char *pchRet)
{
    // Does this char map directly to Unicode?
    if (0x000a == wch ||
        0x000d == wch ||
        (0x0020 <= wch && 0x0023 >= wch) ||
        (0x0025 <= wch && 0x003f >= wch) ||
        (0x0041 <= wch && 0x005a >= wch) ||
        (0x0061 <= wch && 0x007a >= wch))
    {
        *pchRet = (char)(wch & 0x007f);
        return TRUE;
    }
    else
    {
        CHARMAP cmKey = { '\0', wch};
        CHARMAP* pcmFound;

        pcmFound = (CHARMAP*)bsearch(&cmKey, g_rgcmUnicodeToGSMExceptions, NUM_EXCEPTIONS, sizeof(CHARMAP), BSCompareChars);
        if (pcmFound)
        {
            *pchRet = pcmFound->ch;
            return TRUE;
        }
    }
    return FALSE;
}

BOOL GSMCharToUnicode(const char ch, WCHAR *pwchRet)
{
    *pwchRet = g_rgwchGSMToUnicode[ch];
    return TRUE;
}

//
//
//
BOOL GSMHexToGSM(const LPCSTR sIn, const UINT cbIn, __out_bcount( cbOut ) const LPSTR sOut, const UINT cbOut, UINT& rcbUsed)
{
    LPCSTR pchIn = sIn;
    LPCSTR pchInEnd = sIn + cbIn;
    LPSTR pchOut = sOut;
    LPCSTR pchOutEnd = sOut + cbOut;
    BOOL fRet = FALSE;

    while (pchIn < pchInEnd - 1 && pchOut < pchOutEnd)
    {
        *pchOut++ = SemiByteCharsToByte(*pchIn, *(pchIn + 1));
        pchIn += 2;
    }

    rcbUsed = pchOut - sOut;
    fRet = TRUE;
    return fRet;
}


//
//
//
BOOL GSMToGSMHex(const LPCSTR sIn, const UINT cbIn, __out_bcount( cbOut ) const LPSTR sOut, const UINT cbOut, UINT& rcbUsed)
{
    LPCSTR pchIn = sIn;
    LPCSTR pchInEnd = sIn + cbIn;
    LPSTR pchOut = sOut;
    LPCSTR pchOutEnd = sOut + cbOut;
    BOOL fRet = FALSE;

    while (pchIn < pchInEnd && pchOut < pchOutEnd - 1)
    {
        *pchOut = g_rgchSemiByteToCharMap[((*pchIn) & 0xf0) >> 4];
        pchOut++;
        *pchOut = g_rgchSemiByteToCharMap[(*pchIn) & 0x0f];
        pchOut++;

        pchIn++;
    }

    rcbUsed = pchOut - sOut;
    fRet = TRUE;
    return fRet;
}

//
// Convert a specified string from Unicode
//
BOOL ConvertFromUnicode(const ENCODING_TYPE enc, const LPCWSTR wsIn, const UINT cchIn, __out_bcount( cbOut ) const LPSTR sOut, const UINT cbOut,
                        UINT& rcbUsed)
{
    FUNCTION_TRACE(ConvertFromUnicode);
    LPCWSTR pwchInEnd;
    LPCWSTR pwchIn;
    LPCSTR pchOutEnd;
    LPSTR pchOut;
    LPSTR sOutTemp = NULL;
    LPCSTR pchOutTemp;
    UINT cbOutUsed;
    char ch7Bit;
    UINT nBits = 0;
    BOOL fRet = FALSE;

    rcbUsed = 0;

    if (ENCODING_GSMDEFAULT == enc)
    {
        pwchInEnd = wsIn + cchIn;
        pchOutEnd = sOut + cbOut;
        pwchIn = wsIn;
        pchOut = sOut;

        while (pwchIn < pwchInEnd && pchOut < pchOutEnd)
        {
            if (!nBits)
            {
                if (!UnicodeCharToGSM(*pwchIn++,pchOut))
                {
                    *pchOut = '?';
                }
                DEBUGCHK(*pchOut < 0x80);
            }
            else
            {
                if (!UnicodeCharToGSM(*pwchIn++,&ch7Bit))
                {
                    ch7Bit = '?';
                }
                DEBUGCHK(ch7Bit < 0x80);
                *pchOut++ += ch7Bit << (8 - nBits);
                *pchOut    = ch7Bit >> nBits;
            }
            nBits = (nBits + 1) % 8;
        }

        if (!nBits && pchOut > sOut)
        {
            // We incremented the destination pointer once too many
            pchOut--;
        }

        // Do various tricks to distinguish fill bits from real characters (GSM 03.38, ver. 6.0.1, chap. 6.1.2.3.1)
        // NOTE: <CR> in GSM default alphabet maps directly to Unicode <CR>
        if ( pchOut >= pchOutEnd )
        {
            ASSERT( FALSE );
            goto Error;
        }

        if (7 == cchIn % 8 && !(*pchOut & 0xfe))
        {
            // We have 7 fill 0-bits at the end -- need to replace them with <CR>
            *pchOut &= 0x01;
            *pchOut |= ('\r' << 1);
        }
        else if (!(cchIn % 8) && pchOut < pchOutEnd - 1 && ('\r' << 1) == *pchOut)
        {
            // We have no fill bits and the last character in the text is <CR> --
            //    we need to add another <CR>, so that terminating <CR> isn't confused with fill bits
            pchOut++;
            *pchOut = '\r' & 0x7f;
        }

        rcbUsed = pchOut - sOut + 1;
        fRet = TRUE;
    }
    else if (ENCODING_GSMDEFAULT_UNPACKED == enc)
    {
        DWORD dwCharCount = 0;
        while ((dwCharCount < cchIn) && (dwCharCount < cbOut))
        {
            if (!UnicodeCharToGSM(wsIn[dwCharCount], &(sOut[dwCharCount])))
            {
                sOut[dwCharCount] = '?';
            }
            dwCharCount++;
        }
        rcbUsed = cchIn;
        fRet = TRUE;
    }
    else if ((ENCODING_GSMDEFAULT_HEX == enc) || (ENCODING_GSMDEFAULT_HEX_UNPACKED == enc))
    {
        ENCODING_TYPE etSubEncoding;
        if (ENCODING_GSMDEFAULT_HEX_UNPACKED == enc)
        {
            etSubEncoding = ENCODING_GSMDEFAULT_UNPACKED;
        }
        else
        {
            etSubEncoding = ENCODING_GSMDEFAULT;
        }
        sOutTemp = new char[cbOut / 2 + 1];
        if (!sOutTemp)
        {
            goto Error;
        }
        if (!ConvertFromUnicode(etSubEncoding, wsIn, cchIn, sOutTemp, cbOut / 2 + 1, cbOutUsed))
        {
            goto Error;
        }

        pchOutTemp = sOutTemp;
        pchOut = sOut;
        pchOutEnd = sOut + cbOut;

        while ((pchOut <= pchOutEnd) && ((cbOutUsed--) > 0))
        {
            *pchOut++ = SemiByteToChar(*pchOutTemp, TRUE);
            *pchOut++ = SemiByteToChar(*pchOutTemp++, FALSE);
        }
        fRet = TRUE;
        rcbUsed = pchOut - sOut;
    }
    else if (ENCODING_GSMDEFAULT_UNICODE == enc)
    {
        pwchIn = wsIn;
        pwchInEnd = wsIn + cchIn;

        pchOut = sOut;
        pchOutEnd = sOut + cbOut;

        while (pwchIn < pwchInEnd && (pchOut+3) < pchOutEnd)
        {
            pchOut[0] = g_rgchSemiByteToCharMap[ (int)(( *pwchIn >> 12 ) & 0x0f ) ];
            pchOut[1] = g_rgchSemiByteToCharMap[ (int)(( *pwchIn >> 8 ) & 0x0f ) ];
            pchOut[2] = g_rgchSemiByteToCharMap[ (int)(( *pwchIn >> 4 ) & 0x0f ) ];
            pchOut[3] = g_rgchSemiByteToCharMap[ (int)( *pwchIn & 0x0f ) ];

            pwchIn++;
            pchOut += 4;
        }

        rcbUsed = pchOut - sOut;
        fRet = TRUE;
    }
    else if (ENCODING_GSMDEFAULT_UTF8 == enc)
    {
        pwchIn = wsIn;
        pwchInEnd = wsIn + cchIn;

        pchOut = sOut;
        pchOutEnd = sOut + cbOut;

        while (pwchIn < pwchInEnd)
        {
            WCHAR wch = *pwchIn++;

            if (0 == (wch & 0xFF80))
            {   // 7 bits
                if (pchOut + 1 > pchOutEnd)
                    goto Error;
                *pchOut++ = (char) wch;
            }
            else if (0 == (wch & 0xF800))
            {   // 11 bits
                if (pchOut + 2 > pchOutEnd)
                    goto Error;
                *pchOut++ = (char) (0xC0 | ((wch >> 6) & 0x1F));
                *pchOut++ = (char) (0x80 | (wch & 0x3F));
            }
            else
            {   // 16 bits
                if (pchOut + 3 > pchOutEnd)
                    goto Error;
                *pchOut++ = (char) (0xE0 | ((wch >> 12) & 0x0F));
                *pchOut++ = (char) (0x80 | ((wch >> 6) & 0x3F));
                *pchOut++ = (char) (0x80 | (wch & 0x3F));
            }

⌨️ 快捷键说明

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