📄 parse.cpp
字号:
/*++
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:
--*/
#include "precomp.h"
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;
LPSTR szTemp = strstr(szString, szMatch);
if (!szTemp)
{
goto End;
}
fRet = (szTemp == szString);
if (fRet)
{
rszPointer = szString + strlen(szMatch);
#ifdef EMP_DRIVER
// On EMP platform, more space characters may occur
while (' ' == *rszPointer)
{
rszPointer++;
}
#endif
}
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;
#ifdef EMP_DRIVER
// On EMP platform, a quoted string embraced by brackets is also a valid string
BOOL fBracketed = FALSE;
if (*rszPointer == '(')
{
fBracketed = TRUE;
rszPointer++;
}
#endif
// 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';
#ifdef EMP_DRIVER
// On EMP platform, a quoted string embraced by brackets is also a valid string
if (fBracketed)
{
if (*rszPointer != ')')
{
fRet = FALSE;
goto Error;
}
rszPointer++;
}
#endif
Error:
if (!fRet)
{
rszPointer = szData;
}
return fRet;
}
BOOL ParseUCS2String(const LPCSTR szData, const LPWSTR pwszOut, const UINT cbOut, LPCSTR& rszPointer)
{
// TBD_FUNCTION(ParseUCS2String);
BOOL fRet = FALSE;
rszPointer = szData;
if(!ParseQuotedEncodedString(ENCODING_UCS2, rszPointer, pwszOut, pwszOut+cbOut))
{
goto Error;
}
fRet = TRUE;
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -