windows-nt/Source/XPSP1/NT/com/oleutest/stgbvt/comtools/cmdlinew/culong.cxx

326 lines
9.4 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//+------------------------------------------------------------------
//
// File: culong.cxx
//
// Contents: implementation for CUlongCmdlineObj
//
// Synoposis: Encapsulates a command line switch which takes an
// unsigned long value, eg: /maxusers:10
//
// Classes: CUlongCmdlineObj
//
// Functions:
//
// History: 06/15/92 DeanE Stolen from CIntCmdlineObj code
// 07/29/92 davey Added nlsType and nlsLineArgType
// 09/09/92 Lizch Changed SUCCESS to NO_ERROR
// 09/18/92 Lizch Precompile headers
// 11/14/92 DwightKr Updates for new version of NLS_STR
// 10/14/93 DeanE Converted to NCHAR
//
//-------------------------------------------------------------------
#include <comtpch.hxx>
#pragma hdrstop
#include <cmdlinew.hxx> // public cmdlinew stuff
#include "_clw.hxx" // private cmdlinew stuff
#include <ctype.h> // is functions
INT StringToUlong(LPCNSTR pnszInt, ULONG *pUlong);
LPCNSTR nszCmdlineUlong = _TEXTN("Takes an unsigned long ");
LPCNSTR nszLineArgUlong = _TEXTN("<ulong> ");
//+------------------------------------------------------------------
//
// Member: CUlongCmdlineObj destructor
//
// Synoposis: Frees any memory associated with the object
//
// History: Added to allow casting of pValue 05/12/92 Lizch
// Integrated into CUlongCmdlineObj 6/15/92 DeanE
//
//-------------------------------------------------------------------
CUlongCmdlineObj::~CUlongCmdlineObj()
{
delete (ULONG *)_pValue;
_pValue = NULL;
}
//+------------------------------------------------------------------
//
// Member: CUlongCmdlineObj::SetValue, public
//
// Synposis: Stores the ulong value specified after the switch
// string, eg. 10 for /maxusers:10
//
// Effects: This implementation for the virtual method SetValue
// converts the characters following the switch to an unsigned
// long. It allocates memory for the ulong.
// If there is no equator character, or if there
// is no character following the equator character, _pValue
// remains NULL.
//
// Arguments: [nszArg] - the string following the switch on the
// command line. Includes the equator (eg.
// ':' or '=' ), if any.
//
// Returns: CMDLINE_NO_ERROR, CMDLINE_ERROR_OUT_OF_MEMORY,
// CMDLINE_ERROR_TOO_BIG, CMDLINE_ERROR_INVALID_VALUE
//
// History: Created 12/27/91 Lizch
// Converted to NLS_STR 4/17/92 Lizch
// Integrated into CUlongCmdlineObj 6/15/92 DeanE
//
//-------------------------------------------------------------------
INT CUlongCmdlineObj::SetValue(LPCNSTR nszArg)
{
INT iRC;
// delete any existing _pValue
delete (ULONG *)_pValue;
_pValue = NULL;
_pValue = new ULONG;
if (_pValue == NULL)
{
return (CMDLINE_ERROR_OUT_OF_MEMORY);
}
// I'm using this rather than c runtime atol so that I
// can detect error conditions like overflow and non-digits.
iRC = StringToUlong(nszArg, (ULONG *)_pValue);
if (iRC != CMDLINE_NO_ERROR)
{
delete (ULONG *)_pValue;
_pValue = NULL;
}
return(iRC);
}
//+------------------------------------------------------------------
//
// Member: CUlongCmdlineObj::GetValue, public
//
// Synposis: Returns a pointer to ULONG that holds the value.
//
// Arguments: void
//
// Returns: ULONG value at *_pValue.
//
// History: Created 12/27/91 Lizch
// Converted to NLS_STR 4/17/92 Lizch
// Integrated into CUlongCmdlineObj 6/15/92 DeanE
//
//-------------------------------------------------------------------
const ULONG *CUlongCmdlineObj::GetValue()
{
return((ULONG *)_pValue);
}
//+------------------------------------------------------------------
//
// Member: CUlongCmdlineObj::DisplayValue, public
//
// Synoposis: Prints the stored command line value accordint to
// current display method. Generally this will be to stdout.
//
// History: Created 12/27/91 Lizch
// Converted to NLS_STR 4/17/92 Lizch
// Integrated into CUlongCmdlineObj 6/15/92 DeanE
//
//-------------------------------------------------------------------
void CUlongCmdlineObj::DisplayValue()
{
if (_pValue != NULL)
{
_sNprintf(_nszErrorBuf,
_TEXTN("Command line switch %s has value %lu\n"),
_pnszSwitch,
*(ULONG *)_pValue);
(*_pfnDisplay)(_nszErrorBuf);
}
else
{
DisplayNoValue();
}
}
//+------------------------------------------------------------------
//
// Function: StringToUlong
//
// Synoposis: Converts given string to unsigned long, checking for
// overflow and illegal characters. Only +, - and digits
// are accepted.
//
// Arguments: [nszUlong] - string to convert
// [pUlong] - pointer to converted unsigned long
//
// Returns: CMDLINE_NO_ERROR, CMDLINE_ERROR_INVALID_VALUE,
// CMDLINE_ERROR_TOO_BIG
//
// History: Created 12/17/91 Lizch
// Converted to AsciiToUlong 6/15/92 DeanE
// Added in conversion of Hex 12/27/94 DaveY
//
// Notes: I'm using this rather than c runtime atoi so that I
// can detect error conditions like overflow and non-digits.
// The sign is checked for and stored, although it is not
// used - so a negative value will still be converted to
// an unsigned equivalent.
//
//-------------------------------------------------------------------
INT StringToUlong(LPCNSTR nszUlong, ULONG *pUlong)
{
short sNegator = 1;
ULONG ulResult = 0;
INT iRC = CMDLINE_NO_ERROR;
// Skip any leading spaces - these can occur if the command line
// switch incorporates spaces, eg "/a: 123"
//
while (_isnspace(*nszUlong))
{
nszUlong++;
}
// Get sign - ignore for now
switch (*nszUlong)
{
case '-':
sNegator = -1;
nszUlong++;
break;
case '+':
sNegator = 1;
nszUlong++;
break;
default:
break;
}
// see if using hex values
if ((*nszUlong == _TEXTN('0')) &&
((*(nszUlong+1) == _TEXTN('x')) || (*(nszUlong+1) == _TEXTN('X'))))
{
nszUlong += 2; // pass the "0x"
int max = sizeof(ULONG) << 1; // number of hex digits possible
for(int i=0; *nszUlong != NULL && i < max; i++, nszUlong++)
{
if ((_TEXTN('0') <= *nszUlong ) && (*nszUlong <= _TEXTN('9')))
{
ulResult = ulResult * 16 + (*nszUlong - _TEXTN('0'));
}
else if ((_TEXTN('A') <= *nszUlong ) && (*nszUlong <= _TEXTN('F')))
{
ulResult = ulResult * 16 + 10 + (*nszUlong - _TEXTN('A'));
}
else if ((_TEXTN('a') <= *nszUlong) && (*nszUlong <= _TEXTN('f')))
{
ulResult = ulResult * 16 + 10 + (*nszUlong - _TEXTN('a'));
}
else
{
iRC = CMDLINE_ERROR_INVALID_VALUE;
ulResult = 0;
break;
}
}
if ((i >= max) && (*nszUlong != NULL))
{
iRC = CMDLINE_ERROR_INVALID_VALUE;
ulResult = 0;
}
*pUlong = ulResult;
return iRC;
}
// must be decimal
for (;*nszUlong != L'\0'; nszUlong++)
{
if (!_isndigit(*nszUlong))
{
ulResult = 0;
iRC = CMDLINE_ERROR_INVALID_VALUE;
break;
}
ULONG ulPrevious = ulResult;
ulResult = (ulResult * 10) + (*nszUlong - '0');
// Check for overflow by checking that the previous result is less
// than the current result - if the previous one was bigger, we've
// overflowed!
//
if (ulResult < ulPrevious)
{
ulResult = 0;
iRC = CMDLINE_ERROR_TOO_BIG;
break;
}
}
*pUlong = ulResult;
return(iRC);
}
//+-------------------------------------------------------------------
//
// Method: CUlongCmdlineObj::QueryCmdlineType, protected, const
//
// Synoposis: returns a character pointer to the cmdline type.
//
// Arguments: None.
//
// Returns: const NCHAR pointer to string.
//
// History: 28-Jul-92 davey Created.
//
//--------------------------------------------------------------------
LPCNSTR CUlongCmdlineObj::QueryCmdlineType() const
{
return(nszCmdlineUlong);
}
//+-------------------------------------------------------------------
//
// Method: CUlongCmdlineObj::QueryLineArgType, protected, const
//
// Synoposis: returns a character pointer to the line arg type.
//
// Arguments: None.
//
// Returns: const NLS_STR reference to string.
//
// History: 28-Jul-92 davey Created.
//
//--------------------------------------------------------------------
LPCNSTR CUlongCmdlineObj::QueryLineArgType() const
{
// if user has not defined one then give default one
if (_pnszLineArgType == NULL)
{
return(nszLineArgUlong);
}
else
{
return(_pnszLineArgType);
}
}