📄 parse.cpp
字号:
{
// 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;
}
return FALSE;
}
case 0x81:
case 0x82:
{
// Make sure at least 3 bytes of data
if ( (pszIn+3) > pszInEnd )
{
return FALSE;
}
// Second octet is # of characters in the string
BYTE Length = (BYTE)*pszIn++;
WCHAR UCSBase;
if (c==0x81)
{
// Third octet is bits 14-7 of the base pointer
UCSBase = CAST_CTOW(*pszIn++) << 7;
}
else
{
// Third & fourth octets are the base pointer
UCSBase = CAST_CTOW(*pszIn++) << 8;
UCSBase += CAST_CTOW(*pszIn++);
}
if (pszIn>=pszInEnd)
{
return FALSE;
}
while (pwszOut < pwszOutEnd)
{
if (pszIn==pszInEnd)
{
*pwszOut = L'\0';
return TRUE;
}
c = *pszIn++;
if (c & 0x80)
{
// If high bit is set, lower 7 bits constitute the lowest 7 bits added to the base pointer
*pwszOut = UCSBase + CAST_CTOW(c & 0x7f);
}
else
{
// This is a GSM default alphabet character
*pwszOut = CAST_CTOW(c); // Avoid sign-extension
}
pwszOut++;
}
return FALSE;
}
default:
{
// Normal string data - similar to ParseString above
while (pwszOut < pwszOutEnd)
{
GSMCharToUnicode(c, pwszOut);
pwszOut++;
if (pszIn==pszInEnd)
{
*pwszOut = L'\0';
return TRUE;
}
c = *pszIn++;
}
return FALSE;
}
}
return FALSE;
}
BOOL ParseStringHexW(LPCSTR pszIn, const LPCSTR pszInEnd, LPWSTR pwszOut, const LPWSTR pwszOutEnd)
{
BOOL bRet;
// Handle empty string (must have at least two characters).
if ( (pszIn+2) > pszInEnd )
{
*pwszOut = L'\0';
return TRUE;
}
UINT cbInTmp = ((pszInEnd-pszIn)>>1);
LPSTR pszInTmp = (LPSTR)LocalAlloc(0,cbInTmp);
if (!pszInTmp)
{
return FALSE;
}
bRet = GSMHexToGSM(pszIn, pszInEnd-pszIn, pszInTmp, cbInTmp, cbInTmp);
if (!bRet)
{
goto Exit;
}
bRet = ParseStringGSMW(pszInTmp, pszInTmp+cbInTmp, pwszOut, pwszOutEnd);
Exit:
LocalFree(pszInTmp);
return bRet;
}
BOOL ParseStringUnicodeW(LPCSTR pszIn, const LPCSTR pszInEnd, LPWSTR pwszOut, const LPWSTR pwszOutEnd)
{
// Handle empty string
if (pszIn==pszInEnd)
{
*pwszOut = L'\0';
return TRUE;
}
UINT cbLen = 0;
BOOL fRet = ConvertToUnicode(ENCODING_GSMDEFAULT_UNICODE,
pszIn, ( pszInEnd - pszIn ),
pwszOut, ( pwszOutEnd - pwszOut ),
cbLen);
if ( fRet )
{
if ( cbLen < (UINT)( pwszOutEnd - pwszOut ) )
{
pwszOut[cbLen] = L'\0';
}
else
{
fRet = FALSE;
}
}
return fRet;
}
BOOL ParseStringUTF8W(LPCSTR pszIn, const LPCSTR pszInEnd, LPWSTR pwszOut, const LPWSTR pwszOutEnd)
{
// Handle empty string
if (pszIn==pszInEnd)
{
*pwszOut = L'\0';
return TRUE;
}
UINT cbLen = 0;
BOOL fRet = ConvertToUnicode(ENCODING_GSMDEFAULT_UTF8,
pszIn, ( pszInEnd - pszIn ),
pwszOut, ( pwszOutEnd - pwszOut ),
cbLen);
if ( fRet )
{
if ( cbLen < (UINT)( pwszOutEnd - pwszOut ) )
{
pwszOut[cbLen] = L'\0';
}
else
{
fRet = FALSE;
}
}
return fRet;
}
BOOL ParseStringUCS2(LPCSTR pszIn, const LPCSTR pszInEnd, LPWSTR pwszOut, const LPWSTR pwszOutEnd)
{
BOOL bRet;
UINT cbCount;
LPSTR pszInBuf;
// Handle empty string (must have at least two characters).
if ((pszIn+2) > pszInEnd)
{
*pwszOut = L'\0';
return TRUE;
}
UINT cbInTmp = ((pszInEnd - pszIn) >> 1);
LPSTR pszInTmp = (LPSTR)LocalAlloc(0, cbInTmp);
pszInBuf = pszInTmp;
if (!pszInTmp)
{
return FALSE;
}
bRet = GSMHexToGSM(pszIn, pszInEnd-pszIn, pszInTmp, cbInTmp, cbInTmp);
if (!bRet)
{
goto Exit;
}
for (cbCount = 0; cbCount < cbInTmp; cbCount += 2)
{
if (pwszOut >= pwszOutEnd) break;
*pwszOut = (((BYTE)(pszInTmp[cbCount])) << 8);
*pwszOut |= ((BYTE)(pszInTmp[cbCount + 1]));
pwszOut++;
}
*pwszOut = L'\0';
bRet = TRUE;
Exit:
LocalFree(pszInBuf);
return bRet;
}
BOOL ParseEncodedString(ENCODING_TYPE enc, LPCSTR pszIn, const LPCSTR pszInEnd, LPWSTR pwszOut, const LPWSTR pwszOutEnd)
{
switch (enc)
{
case ENCODING_GSMDEFAULT:
return ParseStringGSMW(pszIn, pszInEnd, pwszOut, pwszOutEnd);
case ENCODING_GSMDEFAULT_HEX:
return ParseStringHexW(pszIn, pszInEnd, pwszOut, pwszOutEnd);
case ENCODING_GSMDEFAULT_UNICODE:
return ParseStringUnicodeW(pszIn, pszInEnd, pwszOut, pwszOutEnd);
case ENCODING_GSMDEFAULT_UTF8:
return ParseStringUTF8W(pszIn, pszInEnd, pwszOut, pwszOutEnd);
case ENCODING_UCS2:
return ParseStringUCS2(pszIn, pszInEnd, pwszOut, pwszOutEnd);
}
return FALSE;
}
BOOL ParseQuotedEncodedString(ENCODING_TYPE enc, LPCSTR& pszIn, LPWSTR pwszOut, const LPWSTR pwszOutEnd)
{
LPCSTR pszInTmp = pszIn;
// Skip over the leading quote
DWORD c;
c = *pszInTmp++;
if (c != '\"')
{
return FALSE;
}
// Calculate string length
LPCSTR pszInEnd = strchr(pszInTmp, '\"');
if (!pszInEnd)
{
return FALSE;
}
if (!ParseEncodedString(enc, pszInTmp, pszInEnd, pwszOut, pwszOutEnd))
{
return FALSE;
}
pszIn = pszInEnd+1;
return TRUE;
}
BOOL AppendStringUCS2W(LPCWSTR pwszIn, LPSTR& pszOut, const LPSTR pszOutEnd)
{
LPSTR pszOutTmp = pszOut;
LPCWSTR pwszInTmp = pwszIn;
WCHAR wc;
if (pszOutTmp>=pszOutEnd)
{
return FALSE;
}
*pszOutTmp++ = (BYTE)0x80;
// Iterate through all the characters in the buffer and store
pwszInTmp = pwszIn;
while (wc=*pwszInTmp++)
{
if (pszOutTmp>=pszOutEnd)
{
return FALSE;
}
*pszOutTmp++=(BYTE)(wc>>8);
if (pszOutTmp>=pszOutEnd)
{
return FALSE;
}
*pszOutTmp++=(BYTE)(wc);
}
pszOut = pszOutTmp;
return TRUE;
}
BOOL AppendStringGSMW(LPCWSTR pwszIn, LPSTR& pszOut, const LPSTR pszOutEnd, BOOL bAllowUnicode, BOOL bFilterGsmChars)
{
LPSTR pszOutTmp = pszOut;
LPCWSTR pwszInTmp = pwszIn;
WCHAR wc;
while (wc=*pwszInTmp++)
{
// If character can't be converted to GSM,
// or if it's a control character (which can screw up the module)
// or if it's a double-quote character (which will also screw up the module)
// Then skip it (or switch to Unicode if allowed)
char c;
if ( (!UnicodeCharToGSM(wc, &c)) ||
(bFilterGsmChars && ((c<32) || (c=='\"'))) )
{
if (bAllowUnicode)
{
// Append in unicode mode
return AppendStringUCS2W(pwszIn,pszOut,pszOutEnd);
}
else
{
// Skip the character
continue;
}
}
if (pszOutTmp>=pszOutEnd)
{
return FALSE;
}
*pszOutTmp++=c;
}
pszOut = pszOutTmp;
return TRUE;
}
BOOL AppendStringHexW(LPCWSTR pwszIn, LPSTR& pszOut, const LPSTR pszOutEnd, BOOL bAllowUnicode)
{
BOOL bRet;
UINT cbIn, cbOut;
// Allocate a buffer to hold the raw (non-hex) gsm characters
cbIn = _tcslen(pwszIn);
// If we might use unicode, we need enough space in the intermediate buffer to hold the Unicode format,
// which takes 2 bytes per unicode char, plus 1 additional byte at the beginning.
if (bAllowUnicode)
{
cbIn = (cbIn<<1) + 1;
}
// Handle empty string.
if (cbIn==0)
{
return TRUE;
}
LPSTR pszIn = (LPSTR)LocalAlloc(0,cbIn);
if (!pszIn)
{
return FALSE;
}
// Pass in a temp ptr, since this will update the ptr and we don't want to lose pszIn.
LPSTR pszInTmp=pszIn;
bRet = AppendStringGSMW(pwszIn, pszInTmp, pszInTmp + cbIn, bAllowUnicode, FALSE);
if (!bRet)
{
goto Exit;
}
cbIn = pszInTmp-pszIn;
cbOut = pszOutEnd-pszOut;
bRet = GSMToGSMHex(pszIn, cbIn, pszOut, cbOut, cbOut);
pszOut = pszOut + cbOut;
Exit:
LocalFree(pszIn);
return bRet;
}
BOOL AppendStringUnicodeW(LPCWSTR pwszIn, LPSTR& pszOut, const LPSTR pszOutEnd, BOOL bAllowUnicode)
{
UINT cbIn = _tcslen( pwszIn );
UINT cbOut = ( pszOutEnd - pszOut );
UINT cbLen = 0;
BOOL fRet = ConvertFromUnicode( ENCODING_GSMDEFAULT_UNICODE, pwszIn, cbIn, pszOut, cbOut, cbLen );
if ( fRet )
{
pszOut += cbLen;
if ( cbLen < cbOut )
{
*pszOut = '\0';
}
else
{
fRet = FALSE;
}
}
return fRet;
}
BOOL AppendStringUTF8W(LPCWSTR pwszIn, LPSTR& pszOut, const LPSTR pszOutEnd, BOOL bAllowUnicode)
{
UINT cbIn = _tcslen( pwszIn );
UINT cbOut = ( pszOutEnd - pszOut );
UINT cbLen = 0;
BOOL fRet = ConvertFromUnicode( ENCODING_GSMDEFAULT_UTF8, pwszIn, cbIn, pszOut, cbOut, cbLen );
if ( fRet )
{
pszOut += cbLen;
if ( cbLen < cbOut )
{
*pszOut = '\0';
}
else
{
fRet = FALSE;
}
}
return fRet;
}
BOOL AppendEncodedString(ENCODING_TYPE enc, LPCWSTR pwszIn, LPSTR& pszOut, const LPSTR pszOutEnd, BOOL bAllowUnicode)
{
switch (enc)
{
case ENCODING_GSMDEFAULT:
return AppendStringGSMW(pwszIn,pszOut,pszOutEnd,bAllowUnicode,TRUE);
case ENCODING_GSMDEFAULT_HEX:
return AppendStringHexW(pwszIn,pszOut,pszOutEnd,bAllowUnicode);
case ENCODING_GSMDEFAULT_UNICODE:
return AppendStringUnicodeW(pwszIn,pszOut,pszOutEnd,bAllowUnicode);
case ENCODING_GSMDEFAULT_UTF8:
return AppendStringUTF8W(pwszIn,pszOut,pszOutEnd,bAllowUnicode);
default:
return FALSE;
}
return FALSE;
}
BOOL AppendQuotedEncodedString(ENCODING_TYPE enc, LPCWSTR pwszIn, LPSTR& pszOut, const PUCHAR pszOutEnd, BOOL bAllowUnicode)
{
BOOL bResult;
LPSTR pszOutTmp = pszOut;
if (pszOutTmp>=(LPSTR)pszOutEnd)
{
return FALSE;
}
*pszOutTmp++='\"';
if (pszOut>=(LPSTR)pszOutEnd)
{
return FALSE;
}
bResult = AppendEncodedString(enc,pwszIn,pszOutTmp,(LPSTR)pszOutEnd,bAllowUnicode);
if (!bResult)
{
return FALSE;
}
*pszOutTmp++='\"';
if (pszOutTmp>=(LPSTR)pszOutEnd)
{
return FALSE;
}
*pszOutTmp='\0'; // Put on a NULL just to be safe
pszOut = pszOutTmp;
return TRUE;
}
//
//
//
BOOL ParseUnquotedString(const LPCSTR szData, const char chDelimiter, const LPSTR szOut, const UINT cbOut, LPCSTR& rszPointer)
{
// FUNCTION_TRACE(ParseUnquotedString);
LPSTR pchOut;
LPSTR szOutEnd;
BOOL fRet = FALSE;
rszPointer = szData;
pchOut = szOut;
szOutEnd = szOut + cbOut;
// Copy the string data until we encounter the delimiter character
while (chDelimiter != *rszPointer && pchOut < szOutEnd - 1)
{
*pchOut++ = *rszPointer++;
}
*pchOut = '\0';
// Skip forward until the delimiter character, if we haven't reached it yet
if (chDelimiter != *rszPointer)
{
rszPointer = strchr(rszPointer, chDelimiter);
if (!rszPointer)
{
// We didn't find the delimiter in the string -- fail
goto Error;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -