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

📄 parse.cpp

📁 手机RILGSM实现的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*++
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.
Copyright (c) 1995-1999  Microsoft Corporation

Module Name:

parse.cpp

Abstract:


Notes:


--*/

/*
#------------------------------------------------------------------------------
#    Revision History
#    Date          	Author         		Activity ID     		            Activity Headline
#    2007-03-22    	hejunlin   		CEDB200048514		     modify for crossbow
#    2008-01-15    	sunruiyang   		WM600029279		     add interface for querying sub array 
#    2008-02-02    	yingmingbo   		WM600030877		     add interface for querying phonebook encode info 
#------------------------------------------------------------------------------
*/


#include "precomp.h"

extern ENCODE_TYPE g_EncodeType;
extern BOOL g_bEncodeHex;

BOOL EncodedStringSizeToUnicodeStringSize(ENCODING_TYPE enc, size_t cbIn, size_t &cbOut)
{
    BOOL bResult = TRUE;
    switch (enc)
    {
    case ENCODING_GSMDEFAULT:
        // In GSM mode, 1 byte of data maps to 2-bytes (1 char) of unicode
        cbOut = cbIn<<1;
        break;

    case ENCODING_GSMDEFAULT_HEX:
        // In hex mode, 2 bytes of hex data map to 2-bytes (1 char) of unicode
        cbOut = cbIn;
        break;

    case ENCODING_GSMDEFAULT_UNICODE:
        // in unicode mode, 4 chars map to 2-bytes (1 char) of unicode
        cbOut = ( cbIn / 2 );
        break;

    case ENCODING_GSMDEFAULT_UTF8:
        cbOut = cbIn<<1;
        break;
    default:
        bResult = FALSE;
    }

    return bResult;
}

//
// Determine if a string starts with another
//
BOOL MatchStringBeginning(const LPCSTR szString, const LPCSTR szMatch, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(MatchStringBeginning);
    BOOL fRet = FALSE;

    LPSTR szTemp = strstr(szString, szMatch);
    if (!szTemp)
    {
        goto End;
    }

    fRet = (szTemp == szString);
    if (fRet)
    {
        rszPointer = szString + strlen(szMatch);
    }

    End:
    return fRet;
}


//
// Determine if a string matches the end of another
//
BOOL MatchStringEnd(const LPCSTR szString, const LPCSTR szMatch, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(MatchStringEnd);
    UINT cbString = strlen(szString);
    UINT cbMatch = strlen(szMatch);
    BOOL fRet = FALSE;

    if (cbString >= cbMatch)
    {
        fRet = !strcmp(szString + cbString - cbMatch, szMatch);
    }
    if (fRet)
    {
        rszPointer = szString + cbString;
        DEBUGCHK('\0' == *rszPointer);
    }
    return fRet;
}



//
// Determine if a string contains another
//
BOOL MatchStringAnywhere(const LPCSTR szString, const LPCSTR szMatch, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(MatchStringAnywhere);
    BOOL fRet = FALSE;

    LPSTR szTemp = strstr(szString, szMatch);
    if (!szTemp)
    {
        goto End;
    }

    rszPointer = szTemp + strlen(szMatch);
    fRet = TRUE;

    End:
    return fRet;
}


//
// Determine if an array of bytes matches the end of another
//
BOOL MatchBytesEnd(const BYTE* const pbBytes, const UINT cbBytes, const BYTE* const pbMatch, const UINT cbMatch,
                   const BYTE*& rpbPointer)
{
    // FUNCTION_TRACE(MatchBytesEnd);
    BOOL fRet = FALSE;

    if (cbBytes >= cbMatch)
    {
        fRet = !memcmp(pbBytes + cbBytes - cbMatch, pbMatch, cbMatch);
    }
    if (fRet)
    {
        rpbPointer = pbBytes + cbBytes;
    }
    return fRet;
}



//
// Determine if an array of bytes contains another
//
BOOL MatchBytesAnywhere(const BYTE* const pbBytes, const UINT cbBytes, const BYTE* const pbMatch, const UINT cbMatch,
                        const BYTE*& rpbPointer)
{
    // FUNCTION_TRACE(MatchBytesAnywhere);
    const BYTE* pbWalk = pbBytes;
    const BYTE* pbEnd = pbBytes + cbBytes;
    BOOL fRet = FALSE;

    while (pbWalk < pbEnd)
    {
        if (!memcmp(pbWalk, pbMatch, cbMatch))
        {
            rpbPointer = pbWalk + cbMatch;
            fRet = TRUE;
            break;
        }

        pbWalk++;
    }
    return fRet;
}


BOOL ParseDWord(const LPCSTR szData, const BOOL fLeadingZerosAllowed, DWORD& rdw, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(ParseDWord);
    int nLeadingDigit = -1;
    BOOL Found=FALSE;

    // Skip any spaces
    SkipChars(szData, rszPointer, " ");

    rdw = 0;

    while (*rszPointer >= '0' && *rszPointer <= '9')
    {
        if (!fLeadingZerosAllowed)
        {
            // Test for leading 0s
            if (-1 == nLeadingDigit)
            {
                // Leading digit hasn't been set yet -- set it now
                nLeadingDigit = *rszPointer - '0';
            }
            else if (!nLeadingDigit)
            {
                // Leading digit is 0 and we got another digit
                // This means that we have leading 0s -- reset the pointer and punt
                Found=FALSE;
                goto Error;
            }
        }

        rdw = rdw * 10 + (*rszPointer - '0');
        rszPointer++;
        Found=TRUE;
    }

    // Skip past any spaces
    SkipChars(rszPointer, rszPointer, " ");

    Error:
    if (!Found)
    {
        rszPointer = szData;
    }
    return Found;
}


BOOL ParseHexDWord(const LPCSTR szData, const BOOL fLeadingZerosAllowed, DWORD& rdw, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(ParseHexDWord);
    int nLeadingDigit = -1;
    UINT nDigit;

    rszPointer = szData;
    rdw = 0;

    while ((*rszPointer >= '0' && *rszPointer <= '9') ||
           (*rszPointer >= 'A' && *rszPointer <= 'F') ||
           (*rszPointer >= 'a' && *rszPointer <= 'f'))
    {
        if (!fLeadingZerosAllowed)
        {
            // Test for leading 0s
            if (-1 == nLeadingDigit)
            {
                // Leading digit hasn't been set yet -- set it now
                nLeadingDigit = *rszPointer - '0';
            }
            else if (!nLeadingDigit)
            {
                // Leading digit is 0 and we got another digit
                // This means that we have leading 0s -- reset the pointer and punt
                rszPointer = szData;
                goto Error;
            }
        }

        // Calculate the digit value
        if (*rszPointer >= 'A' && *rszPointer <= 'F')
        {
            nDigit = 10 + *rszPointer - 'A';
        }
        else if (*rszPointer >= 'a' && *rszPointer <= 'f')
        {
            nDigit = 10 + *rszPointer - 'a';
        }
        else
        {
            nDigit = *rszPointer - '0';
        }

        rdw = rdw * 16 + nDigit;
        rszPointer++;
    }

    Error:
    return (rszPointer > szData);
}

//
//
//
BOOL ParseUInt(const LPCSTR szData, const BOOL fLeadingZerosAllowed, UINT& rnInt, LPCSTR& rszPointer)
{
    return ParseDWord(szData, fLeadingZerosAllowed, (DWORD&)rnInt, rszPointer);
}

//
//
//
BOOL ParseIntAsUInt(const LPCSTR szData, UINT& rnInit, LPCSTR& rszPointer)
{
    BOOL fNegative = FALSE;
    
    rszPointer = szData;

    if (*rszPointer == '-')
    {
        fNegative = TRUE;
        ++rszPointer;
    }

    if (!ParseUInt(rszPointer, FALSE, rnInit, rszPointer))
        return FALSE;

    if (fNegative)
    {
        rnInit = ~rnInit + 1;
    }

    return TRUE;
}

//
//
//
BOOL ParseUIntAndVerifyAbove(const LPCSTR szData, const BOOL fLeadingZerosAllowed, UINT nUpperBound, UINT& rnInt, LPCSTR& rszPointer)
{
    BOOL fRet;

    // Parse the number
    fRet = ParseUInt(szData, fLeadingZerosAllowed, rnInt, rszPointer);

    // Verify that the number is greater than the upper bound
    if (fRet && rnInt >= nUpperBound)
    {
        fRet = FALSE;
        rszPointer = szData;
    }
    return fRet;
}


//
//
//
BOOL ParseUIntAndVerifyBelow(const LPCSTR szData, const BOOL fLeadingZerosAllowed, UINT nLowerBound, UINT& rnInt, LPCSTR& rszPointer)
{
    BOOL fRet;

    // Parse the number
    fRet = ParseUInt(szData, fLeadingZerosAllowed, rnInt, rszPointer);

    // Verify that the number is less than the lower bound
    if (fRet && rnInt <= nLowerBound)
    {
        fRet = FALSE;
        rszPointer = szData;
    }
    return fRet;
}


//
//
//
BOOL ParseHexUInt(const LPCSTR szData, const BOOL fLeadingZerosAllowed, UINT& rnInt, LPCSTR& rszPointer)
{
    return ParseHexDWord(szData, fLeadingZerosAllowed, (DWORD&)rnInt, rszPointer);
}

BOOL ParseFixedPoint(const LPCSTR szData, DWORD &rdwFixedPoint, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(ParseDouble);
    UINT dwIntPart;
    UINT dwFracPart;
    LPCSTR szFracStart;
    rszPointer = szData;

    // Parse the integer part
    if (!ParseUInt(rszPointer, TRUE, dwIntPart, rszPointer))
    {
        goto Error;
    }

    // Shift up by 16 bits
    dwIntPart <<= 16;

    // Parse decimal separator ("." -- this is what GSM uses)
    if ('.' != *rszPointer)
    {
        goto Error;
    }

    // Advance pointer past decimal point
    rszPointer++;

    // Parse the fractional part
    szFracStart=rszPointer;
    if (!ParseUInt(rszPointer, TRUE, dwFracPart, rszPointer))
    {
        goto Error;
    }

    // Shift up by 16 bits
    dwFracPart <<= 16;

    // Now normalize to lie in the lowest 16 bits.
    UINT dwDivisor;
    dwDivisor = 1;
    while (szFracStart<rszPointer)
    {
        dwDivisor*=10;
        szFracStart++;
    }
    dwFracPart/=dwDivisor;

    rdwFixedPoint = dwIntPart+dwFracPart;

    Error:
    return (rszPointer > szData);
}

#if 0 // Not currently used
//
// NOTE: parsing code for the decimal part is imprecise;
//       if higher precision needed, re-write this code.
//
BOOL ParseDouble(const LPCSTR szData, double& rdbDouble, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(ParseDouble);
    UINT nIntPart;
    double dbDivisor;

    rszPointer = szData;
    rdbDouble = 0.0;

    // Parse the integer part
    if (!ParseUInt(rszPointer, TRUE, nIntPart, rszPointer))
    {
        goto Error;
    }
    rdbDouble = (double)nIntPart;

    // Parse decimal separator ("." -- this is what GSM uses)
    if ('.' != *rszPointer)
    {
        goto Error;
    }

    // Advance pointer past decimal point
    rszPointer++;

    // Parse decimal part
    dbDivisor = 10.0;

    while (*rszPointer >= '0' && *rszPointer <= '9')
    {
        rdbDouble += (*rszPointer - '0') / dbDivisor;
        dbDivisor *= 10;
        rszPointer++;
    }

    Error:
    return (rszPointer > szData);
}
#endif

//
//
//
BOOL ParseString(const LPCSTR szData, const LPSTR szOut, const UINT cbOut, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(ParseString);
    LPSTR pchOut;
    LPSTR szOutEnd;
    BOOL fRet = FALSE;

    rszPointer = szData;
    pchOut = szOut;
    szOutEnd = szOut + cbOut;

    // Skip over the leading quote
    if (*rszPointer != '\"')
    {
        goto Error;
    }
    rszPointer++;

    while (pchOut < szOutEnd - 1)
    {
        if (!*rszPointer)
        {
            // We hit the end of the string -- fail
            goto Error;
        }
        else if ('\"' == *rszPointer)
        {
            // Terminating quote -- skip over it and bail out
            rszPointer++;
            fRet = TRUE;
            break;
        }
        else
        {
            *pchOut++ = *rszPointer++;
        }
    }
    *pchOut = '\0';

    Error:
    if (!fRet)
    {
        rszPointer = szData;
    }
    return fRet;
}

#define CAST_CTOW(c) ((WCHAR)((BYTE)(c)))

BOOL ParseStringGSMW(LPCSTR pszIn, const LPCSTR pszInEnd, LPWSTR pwszOut, const LPWSTR pwszOutEnd)
{
    // Handle empty string
    if (pszIn==pszInEnd)
    {
        *pwszOut = L'\0';
        return TRUE;
    }

    BYTE c;
    c = *pszIn++;
    switch (c)
    {
    case 0x80:
        {
            // String data is Unicode bytes in UCS2 encoding
            BOOL fOdd = TRUE;
            while (pwszOut < pwszOutEnd)
            {
                if (pszIn==pszInEnd)
                {
                    // We don't want to fail if the string ends in a partial character.  Just
                    // truncate it.  This will overwrite a trailing 1/2 char with the NULL byte
                    *pwszOut = L'\0';
                    return TRUE;
                }

                c = *pszIn++;

                // Assemble the UCS2 character incrementally
                if (fOdd)
                {
                    *pwszOut = CAST_CTOW(c) << 8;
                }
                else
                {
                    *pwszOut++ |= CAST_CTOW(c);
                }
                fOdd = !fOdd;

⌨️ 快捷键说明

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