|
|
#include "stdafx.h"
#include "utils.h"
#include "globals.h"
#include "trapreg.h"
//***************************************************************************
//
// MapEventToSeverity
//
// Extract the severity field from the event ID and convert it to a
// string equivallent.
//
// Parameters:
// DWORD dwEvent
// The full event ID
//
// CString& sResult
// The severity code string is returned here.
//
// Returns:
// The severity code string is returned via sResult.
//
// Status:
//
//***************************************************************************
void MapEventToSeverity(DWORD dwEvent, CString& sResult) { //
// Values are 32 bit event ID values layed out as follows:
//
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---+-+-+-----------------------+-------------------------------+
// |Sev|C|R| Facility | Code |
// +---+-+-+-----------------------+-------------------------------+
//
// where
//
// Sev - is the severity code
//
// 00 - Success
// 01 - Informational
// 10 - Warning
// 11 - Error
//
// C - is the Customer code flag
//
// R - is a reserved bit
//
// Facility - is the facility code
//
// Code - is the facility's status code
//
//
// Define the facility codes
static UINT auiResource[4] = {IDS_EVENT_SEV_SUCCESS, IDS_EVENT_SEV_INFORMATIONAL, IDS_EVENT_SEV_WARNING, IDS_EVENT_SEV_ERROR }; int iSeverity = (dwEvent >> 30) & 3; sResult.LoadString(auiResource[iSeverity]); }
//********************************************************************************
// FindSubstring
//
// Find a substring in some text and return an index to the starting
// position of the string if it is found.
//
// Parameters:
// LPCSTR pszTemplate
// Pointer to the string to find.
//
// LPCSTR pszText
// Pointer to the text that will be searched
// for the template string.
//
// Returns:
// An index to the location of the substring within the text if it
// is found, otherwise -1.
//
//********************************************************************************
LONG FindSubstring(LPCTSTR pszTemplate, LPCTSTR pszText) { if (*pszTemplate == 0) { // An empty template string matches anything, so return zero.
// This should never really happen since it doesn't make much
// sense to search for nothing.
return 0; }
LPCTSTR pszTextStart = pszText; while (*pszText) { // Iterate through the character positions in the text
// and return the index to the starting char in the string
// if it is found.
LPCTSTR pch1 = pszTemplate; LPCTSTR pch2 = pszText;
while (*pch1 && (*pch1 == *pch2)) { ++pch1; ++pch2; }
if (*pch1 == 0) { // We reached the end of the template string, so there
// must have been a match.
return (LONG)(pszText - pszTextStart); }
++pszText; } // Failed to find the substring
return -1; }
//********************************************************************************
// FindWholeWord
//
// Find a whole word in some text and return an index to the starting
// position of the whole word if it is found. Whole word means the
// specified template string followed by a whitespace or end of string.
//
// Parameters:
// LPCSTR pszTemplate
// Pointer to the "whole word" string to find.
//
// LPCSTR pszText
// Pointer to the text that will be searched
// for the template string.
//
// Returns:
// An index to the location of the "whole word" substring within the text if it
// is found, otherwise -1.
//
//********************************************************************************
LONG FindWholeWord(LPCTSTR pszTemplate, LPCTSTR pszText) { if (*pszTemplate == 0) { // An empty search string matches anything, so return the index
// of the first character.
return 0; }
// Iterate through each character position checking for a whole-word
// match at each position.
LONG nchTemplate = _tcslen(pszTemplate); LPCTSTR pszTextStart = pszText; LPCTSTR pchTextLimit = pszText + (_tcslen(pszText) - nchTemplate); while (pszText <= pchTextLimit) {
// Check to see if the word is contained anywhere within the text
INT iPos = FindSubstring(pszTemplate, pszText); if (iPos == -1) { return -1; }
// Point at the location of the template string within the text
pszText += iPos;
// Get the prefix character
INT ichPrefix; if (pszText == pszTextStart) { // Beginning of line counts as white space.
ichPrefix = _T(' '); } else { ichPrefix = *(pszText - 1); }
// Get the suffix character.
INT ichSuffix = pszText[nchTemplate]; if (ichSuffix == 0) { // End of line counts as whitespace
ichSuffix = _T(' '); }
// To match a whole word, the word must be bounded on either side
// by whitespace.
if (isspace(ichPrefix) && isspace(ichSuffix)) { return (LONG)(pszText - pszTextStart); }
// Bump the text pointer to the next position so we don't do the
// same thing all over again.
++pszText; } return -1; }
void DecString(CString& sValue, int iValue) { // 32 bytes should be enough to hold any value
TCHAR szValue[32]; _itot(iValue, szValue, 10); sValue = szValue; }
void DecString(CString& sValue, long lValue) { // 32 bytes should be enough to hold any value
TCHAR szValue[32]; _ltot(lValue, szValue, 10); sValue = szValue; }
void DecString(CString& sValue, DWORD dwValue) { TCHAR szValue[32]; _ultot(dwValue, szValue, 10); sValue = szValue; }
CList::CList() { m_pndPrev = this; m_pndNext = this; }
void CList::Link(CList*& pndHead) { if (pndHead == NULL) pndHead = this; else {
m_pndNext = pndHead; m_pndPrev = pndHead->m_pndPrev; m_pndPrev->m_pndNext = this; m_pndNext->m_pndPrev = this; } }
void CList::Unlink(CList*& pndHead) { if (pndHead == this) { if (m_pndNext == this) pndHead = NULL; else pndHead = m_pndNext; } m_pndPrev->m_pndNext = m_pndNext; m_pndNext->m_pndPrev = m_pndPrev; }
//***************************************************************
// GetFormattedValue
//
// Convert a value to ASCII and insert thousand separator characters
// into resulting value string.
//
// Parameters:
// CString& sValueDst
// The place to return the converted value.
//
// LONG lValue
// The value to convert.
//
//*****************************************************************
void GetFormattedValue(CString& sValueDst, LONG lValue) { CString sValueSrc; DecString(sValueSrc, lValue);
LONG nch = sValueSrc.GetLength(); LPCTSTR pszSrc = sValueSrc;
// Get a buffer as large as the source string plus the largest number of commas
// plus one for the sign, one for the null terminator plus one character for slop.
LPTSTR pszDst = sValueDst.GetBuffer(nch + nch / 3 + 3);
// Copy any leading sign character.
if ((*pszSrc == _T('+')) || (*pszSrc == _T('-'))) { *pszDst++ = *pszSrc++; --nch; }
// Now copy the rest of the number and insert thousand separator characters in
// the appropriate positions.
LONG nchInitial = nch; while (nch > 0) { if ((nch % 3) == 0) { if (nch != nchInitial) { *pszDst++ = g_chThousandSep; } } *pszDst++ = *pszSrc++; --nch; } *pszDst = _T('\0');
sValueDst.ReleaseBuffer(); }
//**************************************************************
// GenerateRangeMessage
//
// Generate a message indicating that the user should enter a value
// between some numbers nMin and nMax.
//
// Parameters:
// CString& sMessage
// The place to return the message.
//
// LONG nMin
// The minimum valid value in the range.
//
// LONG nMax
// The maximum valid value in the range.
//
//****************************************************************
void GenerateRangeMessage(CString& sMessage, LONG nMin, LONG nMax) { CString sText;
sMessage.LoadString(IDS_RANGE_MESSAGE_PREFIX); sMessage += _T(' ');
GetFormattedValue(sText, nMin); sMessage += sText; sMessage += _T(' ');
sText.LoadString(IDS_RANGE_VALUE_SEPARATOR); sMessage += sText; sMessage += _T(' ');
GetFormattedValue(sText, nMax); sMessage += sText;
sText.LoadString(IDS_SENTENCE_TERMINATOR); sMessage += sText; }
//***************************************************************************
// GetThousandSeparator
//
// Get the thousand separator character for the current locale.
//
// Parameters:
// TCHAR* pchThousandSep
// Pointer to the place to return the thousand separator character.
//
// Returns:
// SCODE
// S_OK if the thousand separator was returned.
// E_FAIL if the thousand separator was not returned.
//
//**************************************************************************
SCODE GetThousandSeparator(TCHAR* pchThousandSep) { // Digit + separator + 3 digits + decimal + two digits + null terminator + 4 slop
#define MAX_CHARS_THOUSAND 12
CString sValue; LPTSTR pszValue = sValue.GetBuffer(MAX_CHARS_THOUSAND);
GetNumberFormat(NULL, 0, _T("1000"), NULL, pszValue, MAX_CHARS_THOUSAND); sValue.ReleaseBuffer();
TCHAR ch = sValue[1]; if (isdigit(ch)) { return E_FAIL; } *pchThousandSep = ch; return S_OK; }
//***********************************************************************
// IsDecimalInteger
//
// This function tests a string to see whether or not it contains a
// valid integer expression.
//
// Parameters:
// LPCTSTR pszValue
// Pointer to the string to test.
//
// Returns:
// BOOL
// TRUE = The string contained a valid integer expression.
// FALSE = The string did not contain a valid integer expression.
//
//***********************************************************************
BOOL IsDecimalInteger(LPCTSTR pszValue) { // Accept leading white space
while (iswspace(*pszValue)) { ++pszValue; }
// Accept a leading plus or minus sign
if ((*pszValue == _T('+')) || (*pszValue == _T('-'))) { ++pszValue; }
// Skip a string of consecutive digits with embedded thousand separators
BOOL bSawThousandSep = FALSE; LONG nDigits = 0; while (TRUE) { if (*pszValue == g_chThousandSep) { if (nDigits > 3) { return FALSE; }
bSawThousandSep = TRUE; nDigits = 0; } else if (isdigit(*pszValue)) { ++nDigits; } else { break; } ++pszValue; }
if (bSawThousandSep && nDigits != 3) { // If a thousand separater was encountered, then there must be
// three digits to the right of the last thousand separator.
return FALSE; }
// Accept trailing whitespace
if (iswspace(*pszValue)) { ++pszValue; }
if (*pszValue == _T('\0')) { // We reached the end of the string, so it must have been a decimal integer.
return TRUE; } else { // We did not rech the end of the string, so it couldn't have been a valid
// decimal integer value.
return FALSE; } }
//***************************************************************************
// AsciiToLong
//
// This function first validates a string to make sure that it is a properly
// formatted integer expression, and then converts it to a long. Any embedded
// characters, such as the thousand separator, are stripped out before the
// conversion is done.
//
//
// Parameters:
// LPCTSTR pszValue
// Pointer to the string value to convert.
//
// LONG* plResult
// Pointer to the place to store the result.
//
// Returns:
// SCODE
// S_OK = The string contained a valid integer and the converted
// value was returned via plResult.
// E_FAIL = The string did not contain a properly formatted integer
// expression.
//
//
//**************************************************************************
SCODE AsciiToLong(LPCTSTR pszValue, LONG* plResult) { if (!IsDecimalInteger(pszValue)) { return E_FAIL; }
// Strip out any superfluous characters, such as the thousand separator
// before converting from ascii to long.
CString sStrippedValue; LPTSTR pszDst = sStrippedValue.GetBuffer(_tcslen(pszValue) + 1); TCHAR ch; while (ch = *pszValue++) { if (isdigit(ch) || ch==_T('+') || ch==_T('-')) { *pszDst++ = ch; } } *pszDst = 0; sStrippedValue.ReleaseBuffer();
*plResult = _ttol(sStrippedValue); return S_OK; }
|