You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
505 lines
11 KiB
505 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
parsers.cxx
|
|
|
|
Abstract:
|
|
|
|
Common text parsing functions (generally moved here from other protocols)
|
|
|
|
Contents:
|
|
ExtractWord
|
|
ExtractDword
|
|
ExtractInt
|
|
SkipWhitespace
|
|
SkipSpaces
|
|
SkipLine
|
|
FindToken
|
|
NiceNum
|
|
|
|
Author:
|
|
|
|
Richard L Firth (rfirth) 03-Jul-1996
|
|
|
|
Revision History:
|
|
|
|
03-Jul-1996 rfirth
|
|
Created
|
|
|
|
--*/
|
|
|
|
#include <wininetp.h>
|
|
|
|
//
|
|
// functions
|
|
//
|
|
|
|
|
|
BOOL
|
|
ExtractWord(
|
|
IN OUT LPSTR* pString,
|
|
IN DWORD NumberLength,
|
|
OUT LPWORD pConvertedNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pulls a <NumberLength> character number out of a string.
|
|
|
|
Assumes: 1. The number to be converted is an unsigned short
|
|
2. A whole number is contained within *pString
|
|
|
|
Arguments:
|
|
|
|
pString - pointer to pointer to string from which to get number
|
|
|
|
NumberLength - number of characters that comprise number string, if
|
|
not equal to 0, else if 0, we don't know the length
|
|
of the number string a priori
|
|
|
|
pConvertedNumber - pointer to variable where converted number written
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - number converted OK
|
|
|
|
FALSE - one of the characters in the number is not a digit
|
|
|
|
--*/
|
|
|
|
{
|
|
WORD number;
|
|
BOOL exact;
|
|
LPSTR string;
|
|
|
|
//
|
|
// if the caller doesn't know how many characters comprise the number, then
|
|
// we will convert until the next non-digit character, or until we have
|
|
// converted the maximum number of digits that can comprise an unsigned
|
|
// short value
|
|
//
|
|
|
|
if (NumberLength == 0) {
|
|
NumberLength = sizeof("65535") - 1;
|
|
exact = FALSE;
|
|
} else {
|
|
exact = TRUE;
|
|
}
|
|
number = 0;
|
|
string = *pString;
|
|
while (NumberLength && isdigit(*string)) {
|
|
number = number * 10 + (WORD)((BYTE)(*string++) - (BYTE)'0');
|
|
--NumberLength;
|
|
}
|
|
*pConvertedNumber = number;
|
|
*pString = string;
|
|
|
|
//
|
|
// if we were asked to convert a certain number of characters but failed
|
|
// because we hit a non-digit character, then return FALSE. Anything else
|
|
// (we converted required number of characters, or the caller didn't know
|
|
// how many characters comprised the number) is TRUE
|
|
//
|
|
|
|
return (exact && (NumberLength != 0)) ? FALSE : TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ExtractDword(
|
|
IN OUT LPSTR* pString,
|
|
IN DWORD NumberLength,
|
|
OUT LPDWORD pConvertedNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pulls a <NumberLength> character number out of a string.
|
|
|
|
Assumes: 1. The number to be converted is an unsigned long
|
|
2. A whole number is contained within *pString
|
|
|
|
Arguments:
|
|
|
|
pString - pointer to pointer to string from which to get number
|
|
|
|
NumberLength - number of characters that comprise number string, if
|
|
not equal to 0, else if 0, we don't know the length
|
|
of the number string a priori
|
|
|
|
pConvertedNumber - pointer to variable where converted number written
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - number converted OK
|
|
|
|
FALSE - one of the characters in the number is not a digit
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD number;
|
|
BOOL exact;
|
|
|
|
//
|
|
// if the caller doesn't know how many characters comprise the number, then
|
|
// we will convert until the next non-digit character, or until we have
|
|
// converted the maximum number of digits that can comprise an unsigned
|
|
// short value
|
|
//
|
|
|
|
if (NumberLength == 0) {
|
|
NumberLength = sizeof("4294967295") - 1;
|
|
exact = FALSE;
|
|
} else {
|
|
exact = TRUE;
|
|
}
|
|
for (number = 0; isdigit(**pString) && NumberLength--; ) {
|
|
number = number * 10 + (DWORD)((BYTE)*((*pString)++) - (BYTE)'0');
|
|
}
|
|
*pConvertedNumber = number;
|
|
|
|
//
|
|
// if we were asked to convert a certain number of characters but failed
|
|
// because we hit a non-digit character, then return FALSE. Anything else
|
|
// (we converted required number of characters, or the caller didn't know
|
|
// how many characters comprised the number) is TRUE
|
|
//
|
|
|
|
return (exact && (NumberLength != 0)) ? FALSE : TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ExtractInt(
|
|
IN OUT LPSTR* pString,
|
|
IN DWORD NumberLength,
|
|
OUT LPINT pConvertedNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
pulls a <NumberLength> character number out of a string.
|
|
|
|
Assumes: 1. The number to be converted is an signed integer (32-bits)
|
|
|
|
Arguments:
|
|
|
|
pString - pointer to pointer to string from which to get number
|
|
|
|
NumberLength - number of characters that comprise number string, if
|
|
not equal to 0, else if 0, we don't know the length
|
|
of the number string a priori
|
|
|
|
pConvertedNumber - pointer to variable where converted number written
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - number converted OK
|
|
|
|
FALSE - one of the characters in the number is not a digit
|
|
|
|
--*/
|
|
|
|
{
|
|
int number;
|
|
int sign;
|
|
BOOL exact;
|
|
|
|
if ((**pString == '-') || (**pString == '+')) {
|
|
sign = (**pString == '-') ? -1 : +1;
|
|
if (NumberLength) {
|
|
--NumberLength;
|
|
}
|
|
++*pString;
|
|
} else {
|
|
sign = 1;
|
|
}
|
|
|
|
//
|
|
// if the caller doesn't know how many characters comprise the number, then
|
|
// we will convert until the next non-digit character, or until we have
|
|
// converted the maximum number of digits that can comprise an unsigned
|
|
// short value
|
|
//
|
|
|
|
if (NumberLength == 0) {
|
|
NumberLength = sizeof("2147483647") - 1;
|
|
exact = FALSE;
|
|
} else {
|
|
exact = TRUE;
|
|
}
|
|
for (number = 0; isdigit(**pString) && NumberLength; ) {
|
|
number = number * 10 + (INT)(((BYTE)**pString) - (BYTE)'0');
|
|
++*pString;
|
|
--NumberLength;
|
|
}
|
|
*pConvertedNumber = number * sign;
|
|
|
|
//
|
|
// if we were asked to convert a certain number of characters but failed
|
|
// because we hit a non-digit character, then return FALSE. Anything else
|
|
// (we converted required number of characters, or the caller didn't know
|
|
// how many characters comprised the number) is TRUE
|
|
//
|
|
|
|
return (exact && (NumberLength != 0)) ? FALSE : TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
SkipWhitespace(
|
|
IN OUT LPSTR* lpBuffer,
|
|
IN OUT LPDWORD lpBufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Skips any whitespace characters
|
|
|
|
Arguments:
|
|
|
|
lpBuffer - pointer to pointer to buffer
|
|
|
|
lpBufferLength - pointer to remaining buffer length
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
Success - TRUE
|
|
|
|
Failure - FALSE. No more data left in buffer
|
|
|
|
--*/
|
|
|
|
{
|
|
while ((*lpBufferLength != 0) && isspace(**lpBuffer)) {
|
|
++*lpBuffer;
|
|
--*lpBufferLength;
|
|
}
|
|
return *lpBufferLength != 0;
|
|
}
|
|
|
|
|
|
BOOL
|
|
SkipSpaces(
|
|
IN OUT LPSTR* lpBuffer,
|
|
IN OUT LPDWORD lpBufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Skips any space characters. We only look for the actual space character
|
|
|
|
Arguments:
|
|
|
|
lpBuffer - pointer to pointer to buffer
|
|
|
|
lpBufferLength - pointer to remaining buffer length
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
Success - TRUE
|
|
|
|
Failure - FALSE. No more data left in buffer
|
|
|
|
--*/
|
|
|
|
{
|
|
while ((*lpBufferLength != 0) && (**lpBuffer == ' ')) {
|
|
++*lpBuffer;
|
|
--*lpBufferLength;
|
|
}
|
|
return *lpBufferLength != 0;
|
|
}
|
|
|
|
|
|
BOOL
|
|
SkipLine(
|
|
IN OUT LPSTR* lpBuffer,
|
|
IN OUT LPDWORD lpBufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Positions text pointer at start of next non-empty line
|
|
|
|
Arguments:
|
|
|
|
lpBuffer - pointer to string. Updated on output
|
|
|
|
lpBufferLength - pointer to remaining length of string. Updated on output
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - found start of next non-empty line
|
|
|
|
FALSE - ran out of buffer
|
|
|
|
--*/
|
|
|
|
{
|
|
while ((*lpBufferLength != 0) && (**lpBuffer != '\r') && (**lpBuffer != '\n')) {
|
|
++*lpBuffer;
|
|
--*lpBufferLength;
|
|
}
|
|
while ((*lpBufferLength != 0) && ((**lpBuffer == '\r') || (**lpBuffer == '\n'))) {
|
|
++*lpBuffer;
|
|
--*lpBufferLength;
|
|
}
|
|
return *lpBufferLength != 0;
|
|
}
|
|
|
|
|
|
#undef isspace
|
|
#define isspace(ch) ((ch==0x20) || ((ch >= 0x09) && (ch <= 0x0d)))
|
|
|
|
BOOL
|
|
FindToken(
|
|
IN OUT LPSTR* lpBuffer,
|
|
IN OUT LPDWORD lpBufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Moves over the current token, past any spaces, and to the start of the next
|
|
token
|
|
|
|
Arguments:
|
|
|
|
lpBuffer - pointer to pointer to buffer
|
|
|
|
lpBufferLength - pointer to remaining buffer length
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
Success - TRUE
|
|
|
|
Failure - FALSE. No more data left in buffer
|
|
|
|
--*/
|
|
|
|
{
|
|
while ((*lpBufferLength != 0) && !isspace(**lpBuffer)) {
|
|
++*lpBuffer;
|
|
--*lpBufferLength;
|
|
}
|
|
while ((*lpBufferLength != 0) && isspace(**lpBuffer)) {
|
|
++*lpBuffer;
|
|
--*lpBufferLength;
|
|
}
|
|
return *lpBufferLength != 0;
|
|
}
|
|
|
|
|
|
LPSTR
|
|
NiceNum(
|
|
OUT LPSTR Buffer,
|
|
IN SIZE_T Number,
|
|
IN int FieldWidth
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts a number to a string. The string is very human-sensible (i.e.
|
|
1,234,567 instead of 1234567. Sometimes its hard to make out these numbers
|
|
when your salary is so large)
|
|
|
|
Arguments:
|
|
|
|
Buffer - place to put resultant string
|
|
|
|
Number - to convert
|
|
|
|
FieldWidth - maximum width of the field, or 0 for "don't care"
|
|
|
|
Return Value:
|
|
|
|
LPSTR
|
|
pointer to Buffer
|
|
|
|
--*/
|
|
|
|
{
|
|
int i;
|
|
|
|
if (Number == 0) {
|
|
if (FieldWidth == 0) {
|
|
Buffer[0] = '0';
|
|
Buffer[1] = '\0';
|
|
} else {
|
|
memset(Buffer, ' ', FieldWidth);
|
|
Buffer[FieldWidth - 1] = '0';
|
|
Buffer[FieldWidth] = '\0';
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// if the caller specified zero for the field width then work out how
|
|
// many characters the string will occupy
|
|
//
|
|
|
|
if (FieldWidth == 0) {
|
|
|
|
SIZE_T n;
|
|
|
|
n = Number;
|
|
++FieldWidth;
|
|
while (n >= 10) {
|
|
n /= 10;
|
|
++FieldWidth;
|
|
}
|
|
|
|
FieldWidth += (FieldWidth / 3) - (((FieldWidth % 3) == 0) ? 1 : 0);
|
|
}
|
|
|
|
//
|
|
// now create the representation
|
|
//
|
|
|
|
Buffer[FieldWidth] = '\0';
|
|
Buffer += FieldWidth;
|
|
i = 0;
|
|
while (Number && FieldWidth) {
|
|
*--Buffer = (char)((Number % 10) + '0');
|
|
--FieldWidth;
|
|
Number /= 10;
|
|
if ((++i == 3) && FieldWidth) {
|
|
if (Number) {
|
|
*--Buffer = ',';
|
|
--FieldWidth;
|
|
i = 0;
|
|
}
|
|
}
|
|
}
|
|
while (FieldWidth--) {
|
|
*--Buffer = ' ';
|
|
}
|
|
}
|
|
return Buffer;
|
|
}
|