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

📄 parse.cpp

📁 ril source code for Windows CE
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 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:

parse.cpp

Abstract:


Notes:


--*/
#include "precomp.h"

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

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:
        // in utf-8 mode, 1 char map to at most 2-bytes (1 char) of unicode
        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;

    LPCSTR 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;

    LPCSTR 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, __out_bcount( cbOut ) const LPSTR szOut, const UINT cbOut, LPCSTR& rszPointer)
{
    // FUNCTION_TRACE(ParseString);
    LPSTR pchOut;
    LPCSTR 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)))

#pragma prefast( suppress: 5457, "Currently PREfast does not support __out_ecount( pwszOutEnd - pwszOut )." )
BOOL ParseStringGSMW(LPCSTR pszIn, const LPCSTR pszInEnd, LPWSTR pwszOut, const LPCWSTR pwszOutEnd)
{
    // Handle empty string
    if (pszIn==pszInEnd)
    {
        *pwszOut = L'\0';
        return TRUE;
    }

⌨️ 快捷键说明

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