|
|
// STRTOHEX.CPP
//
// Utility functions to convert string representations of hexadecimal numbers
// into the numbers themselves.
//
// Note: These functions are in their own file, rather than in STRUTIL.CPP,
// because they use a const array. The current implementation of the linker
// pulls this array into binaries if they use any function in the source file,
// not just the functions which reference this array.
#include "precomp.h"
#include <strutil.h>
// This array maps ASCII chars in the range '0' - 'f' to their hex equivalent.
// INVALID_CHAR_ID is used to mark slots that don't correspond to a valid
// hex char.
const BYTE INVALID_CHAR_ID = (BYTE) -1;
const BYTE rgbHexCharMap[] = { // ASCII 0x30 - 0x3f
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, // ASCII 0x40 - 0x4f
INVALID_CHAR_ID, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, // ASCII 0x50 - 0x5f
INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, INVALID_CHAR_ID, // ASCII 0x60 - 0x67
INVALID_CHAR_ID, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, INVALID_CHAR_ID };
const int cbHexCharMap = ARRAY_ELEMENTS(rgbHexCharMap);
//
// HexStringToQWordA()
//
// Converts a hex ANSI string (without 0x or 0X prefix) to a ULARGE_INTEGER
//
// NOTE: The a-f characters can be lowercase or uppercase
//
// Returns TRUE if successful (the string contained all valid characters)
// Returns FALSE otherwise
//
BOOL NMINTERNAL HexStringToQWordA(LPCSTR pcszString, ULARGE_INTEGER* pqw) { BOOL bRet; ASSERT(pcszString); ASSERT(pqw); pqw->QuadPart = 0ui64; int cchStr = lstrlenA(pcszString); if (cchStr <= CCH_HEX_QWORD) { bRet = TRUE; PDWORD pdwCur = (cchStr < CCH_HEX_DWORD) ? &(pqw->LowPart) : &(pqw->HighPart); for (int i = 0; i < cchStr; i++) { // NOTE: DBCS characters are not allowed
ASSERT(! IsDBCSLeadByte(pcszString[i]));
if (CCH_HEX_DWORD == (cchStr - i)) { pdwCur = &(pqw->LowPart); } DWORD dwDigit = (DWORD) INVALID_CHAR_ID; int iDigit = pcszString[i] - '0';
if (iDigit >= 0 && iDigit < cbHexCharMap) { dwDigit = (DWORD) rgbHexCharMap[iDigit]; }
if (INVALID_CHAR_ID != dwDigit) { *pdwCur = ((*pdwCur) << BITS_PER_HEX_CHAR) + dwDigit; } else { bRet = FALSE; break; } } } else { bRet = FALSE; } return bRet; }
/* D W F R O M H E X */ /*-------------------------------------------------------------------------
%%Function: DwFromHex
Return the DWORD from the hex string. -------------------------------------------------------------------------*/ DWORD DwFromHex(LPCTSTR pchHex) { TCHAR ch; DWORD dw = 0;
while (_T('\0') != (ch = *pchHex++)) {
DWORD dwDigit = (DWORD) INVALID_CHAR_ID; int iDigit = ch - _T('0');
if (iDigit >= 0 && iDigit < cbHexCharMap) { dwDigit = (DWORD) rgbHexCharMap[iDigit]; }
if (INVALID_CHAR_ID != dwDigit) { dw = (dw << 4) + dwDigit; } else break; }
return dw; }
|