Windows2003-3790/inetcore/wininet/common/parsers.cxx
2020-09-30 16:53:55 +02:00

506 lines
11 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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;
}