2025-04-27 07:49:33 -04:00

116 lines
2.5 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998, Microsoft Corp. All rights reserved.
//
// FILE
//
// hexbstr.cpp
//
// SYNOPSIS
//
// This file defines functions for converting BSTR's to and from an
// ANSI hex representation.
//
// MODIFICATION HISTORY
//
// 02/25/1998 Original version.
//
///////////////////////////////////////////////////////////////////////////////
#include <ias.h>
#include <hexbstr.h>
//////////
// Convert a hex digit to the number it represents.
//////////
inline BYTE digit2Num(CHAR digit) throw (_com_error)
{
if (digit >= '0' && digit <= '9')
{
return digit - '0';
}
else if (digit >= 'A' && digit <= 'F')
{
return digit - ('A' - 10);
}
_com_issue_error(E_INVALIDARG);
return 0;
}
//////////
// Convert a number to a hex representation.
//////////
inline CHAR num2Digit(BYTE num) throw ()
{
// 'num' can't be out of range so we don't have to check.
return (num < 10) ? num + '0' : num + ('A' - 10);
}
//////////
// Convert an ANSI hex string to a BSTR. The caller is responsible for freeing
// the returned string.
//////////
BSTR hexToBSTR(PCSTR hex) throw (_com_error)
{
// Compute the length of the BSTR in bytes.
UINT len = strlen(hex)/2;
// Zero bytes is okay; it's just a NULL BSTR.
if (!len) { return NULL; }
// Allocate a temporary buffer for decoding.
PBYTE buf = (PBYTE)_alloca(len);
PBYTE p = buf;
UINT left = len;
// Decode each byte.
while (left--)
{
// High order ...
*p = digit2Num(*hex++) << 4;
// ... then low order.
*p++ |= digit2Num(*hex++);
}
// Allocate a BSTR to hold the bytes.
BSTR retval = SysAllocStringByteLen((PCSTR)buf, len);
// Make sure the allocation succeeded.
if (retval == NULL) { _com_issue_error(E_OUTOFMEMORY); }
return retval;
}
//////////
// Convert a BSTR to an ANSI hex string. The 'hex' buffer must be at least
// 1 + 2 * SysStringByteLen(bstr) bytes long.
//////////
void hexFromBSTR(const BSTR bstr, PSTR hex) throw (_com_error)
{
// How many bytes do we have?
UINT len = SysStringByteLen(bstr);
// Pointer into the byte buffer.
PBYTE p = (PBYTE)bstr;
// Iterate through each byte.
while (len--)
{
// High order ...
*hex++ = num2Digit(*p >> 4);
// ... then low order.
*hex++ = num2Digit(*p++ & 0xF);
}
// Add a null terminator.
*hex = '\0';
}