Click here to Skip to main content
15,892,005 members
Articles / Desktop Programming / MFC

XBitArray - a non-MFC C++ class to manipulate bits in a bit array.

Rate me:
Please Sign up or sign in to vote.
4.74/5 (26 votes)
10 Feb 2004CPOL5 min read 71.5K   1K   37  
XBitArray provides functions to set, test, and find bits in an array of bytes.
// XBitArrayTestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "XBitArrayTest.h"
#include "XBitArrayTestDlg.h"
#include "About.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////////////////////////////////////////////
// CXBitArrayTestDlg dialog

CXBitArrayTestDlg::CXBitArrayTestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CXBitArrayTestDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CXBitArrayTestDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CXBitArrayTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CXBitArrayTestDlg)
	DDX_Control(pDX, IDC_LIST, m_List);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CXBitArrayTestDlg, CDialog)
	//{{AFX_MSG_MAP(CXBitArrayTestDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_TEST, OnTest)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////////
// CXBitArrayTestDlg message handlers

BOOL CXBitArrayTestDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	m_List.SetContextMenuId(IDR_XLISTBOX);
	m_List.AddLine(CXListBox::Blue, CXListBox::White, _T("XBitArray v1.2"));
	m_List.AddLine(CXListBox::Blue, CXListBox::White, _T(""));

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CXBitArrayTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CXBitArrayTestDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CXBitArrayTestDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// bit values for bits in bit array
#define XBITARRAY_STATUS_FREE 1
#define XBITARRAY_STATUS_USED 0

#define ARRAY_SIZE_BYTES	10
#define TEST_FILE			_T("BitArray.dat")
#define REGISTRY_KEY		_T("Software\\CodeProject\\XBitArrayTest")
#define REGISTRY_VALUE		_T("Bit Array")


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void CXBitArrayTestDlg::OnTest() 
{
	int testnumber = 1;

	m_nErrors = 0;

	// bit array of 80 bits, allocated by CXBitArray
	CXBitArray bit1(ARRAY_SIZE_BYTES*8, 1);
	testnumber = RunTest(bit1, testnumber);

	BYTE barray[ARRAY_SIZE_BYTES];
	ZeroMemory(barray, ARRAY_SIZE_BYTES);

	// bit array of 80 bits, allocated on stack
	CXBitArray bit2(barray, ARRAY_SIZE_BYTES*8, 1);
	testnumber = RunTest(bit2, testnumber);

	// create bit array file to test persistence
	CreateBitFile(TEST_FILE, ARRAY_SIZE_BYTES, 1);

	// bit array of 80 bits, read from file
	CXBitArray bit3(TEST_FILE, ARRAY_SIZE_BYTES*8, 1);
	testnumber = RunTest(bit3, testnumber);

	// bit array of 8 bits, allocated by CXBitArray
	CXBitArray bit4(8, 1);
	testnumber = RunTest2(bit4, testnumber);

	// test registry persistence
	testnumber = RunTest3(testnumber);

	// test file persistence
	testnumber = RunTest4(testnumber);

	// test Attach
	testnumber = RunTest5(testnumber);

	m_List.AddString(_T(""));

	if (m_nErrors)
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("%d TESTS RUN ==> %d ERROR%c"), 
			testnumber-1, m_nErrors, (m_nErrors > 1) ? _T('S') : _T(' '));
	else
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("%d TESTS RUN ==> ALL PASSED"), testnumber-1);

}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// test CXBitArray on 80-bit array
int CXBitArrayTestDlg::RunTest(CXBitArray& bit, int testnumber)
{
	CString s;
	int i;

	_ASSERTE(bit.GetArraySizeBytes() == ARRAY_SIZE_BYTES);

	LPBYTE pBitArray = (LPBYTE) bit;


	//-------------------------------------------------------------------------
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("All bits should be initialized to 1"));

	size_t bits_set_to_zero, bits_set_to_one;
	bit.Count(&bits_set_to_zero, &bits_set_to_one);

	if ((bits_set_to_zero != 0) || (bits_set_to_one != 80))
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed (Count)"), testnumber-1);
	}

	BOOL result = TRUE;
	for (i = 0; i < ARRAY_SIZE_BYTES; i++)
	{
		if (pBitArray[i] == 0xFF)
		{
			m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
				_T("pBitArray[%d] = %02X:  should be FF"), i, pBitArray[i]);
		}
		else
		{
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("pBitArray[%d] = %02X:  should be FF"), i, pBitArray[i]);
			result = FALSE;
		}
	}

	m_List.AddString(_T(""));

	if (result)
	{
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("     >>>>> Test %d passed"), testnumber-1);
	}
	else
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing Set"));

	m_List.AddString(_T("Setting bits 0 and 79 to 0"));

	bit.Set(0, XBITARRAY_STATUS_USED);
	bit.Set(79, XBITARRAY_STATUS_USED);

	s.Format(_T("pBitArray[0] = %02X:  should be FE"), pBitArray[0]);
	m_List.AddString(s);
	s.Format(_T("pBitArray[9] = %02X:  should be 7F"), pBitArray[9]);
	m_List.AddString(s);

	m_List.AddString(_T(""));

	if ((pBitArray[0] != 0xFE) || (pBitArray[9] != 0x7F))
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}
	else
	{
		m_List.AddString(_T("Setting bits 0 and 79 to 1"));

		bit.Set(0, XBITARRAY_STATUS_FREE);
		bit.Set(79, XBITARRAY_STATUS_FREE);

		s.Format(_T("pBitArray[0] = %02X:  should be FF"), pBitArray[0]);
		m_List.AddString(s);
		s.Format(_T("pBitArray[9] = %02X:  should be FF"), pBitArray[9]);
		m_List.AddString(s);

		m_List.AddString(_T(""));

		if ((pBitArray[0] != 0xFF) || (pBitArray[9] != 0xFF))
		{
			m_nErrors++;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("     >>>>> Test %d failed"), testnumber-1);
		}
		else
		{
			m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
				_T("     >>>>> Test %d passed"), testnumber-1);
		}
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing Get"));
	m_List.AddString(_T(""));

	if (!bit.Get(0))
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}
	else
	{
		if (!bit.Get(79))
		{
			m_nErrors++;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("     >>>>> Test %d failed"), testnumber-1);
		}
		else
		{
			bit.Set(0, XBITARRAY_STATUS_USED);
			bit.Set(79, XBITARRAY_STATUS_USED);

			if (bit.Get(0))
			{
				m_nErrors++;
				m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
					_T("     >>>>> Test %d failed"), testnumber-1);
			}
			else
			{
				if (bit.Get(79))
				{
					m_nErrors++;
					m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
						_T("     >>>>> Test %d failed"), testnumber-1);
				}
				else
				{
					m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
						_T("     >>>>> Test %d passed"), testnumber-1);
				}
			}
		}
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing SetAll"));
	m_List.AddString(_T(""));

	bit.SetAll(0);

	BOOL bSuccess = TRUE;

	for (i = 0; i < ARRAY_SIZE_BYTES; i++)
	{
		if (pBitArray[i] != 0)
		{
			bSuccess = FALSE;
			break;
		}
	}

	if (bSuccess)
	{
		bit.SetAll(1);

		for (i = 0; i < ARRAY_SIZE_BYTES; i++)
		{
			if (pBitArray[i] != 0xFF)
			{
				bSuccess = FALSE;
				break;
			}
		}
	}

	if (bSuccess)
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("     >>>>> Test %d passed"), testnumber-1);
	else
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing Find"));
	m_List.AddString(_T(""));

	// set all bits to used
	bit.SetAll(XBITARRAY_STATUS_USED);

	bSuccess = TRUE;
	size_t free_pos;

	// testing no free bits
	BOOL rc = bit.Find(0, XBITARRAY_STATUS_FREE, &free_pos);
	if (rc)
		bSuccess = FALSE;

	if (bSuccess)
	{
		// set 1 bit to free
		bit.Set(72, XBITARRAY_STATUS_FREE);

		rc = bit.Find(76, XBITARRAY_STATUS_FREE, &free_pos);	// 76 will force wrap
		if (!rc)
			bSuccess = FALSE;

		if (bSuccess)
		{
			if (free_pos != 72)
			{
				bSuccess = FALSE;
			}
			else
			{
				rc = bit.Find(0, XBITARRAY_STATUS_FREE, &free_pos);
				if (!rc)
					bSuccess = FALSE;

				if (bSuccess)
				{
					if (free_pos != 72)
					{
						bSuccess = FALSE;
					}
					else
					{
						// set all bits to free
						bit.SetAll(XBITARRAY_STATUS_FREE);
						bit.Set(36, XBITARRAY_STATUS_USED);

						rc = bit.Find(37, XBITARRAY_STATUS_USED, &free_pos);
						if (!rc)
							bSuccess = FALSE;
						if (free_pos != 36)
							bSuccess = FALSE;

						// test Count
						bit.Count(&bits_set_to_zero, &bits_set_to_one);

						if ((bits_set_to_zero != 1) || (bits_set_to_one != 79))
						{
							m_nErrors++;
							m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
								_T("     >>>>> Test %d failed (Count)"), testnumber-1);
						}

						bit.Set(37, XBITARRAY_STATUS_USED);
						bit.Set(38, XBITARRAY_STATUS_USED);
						bit.Set(39, XBITARRAY_STATUS_USED);
						bit.Set(40, XBITARRAY_STATUS_USED);

						bit.Count(&bits_set_to_zero, &bits_set_to_one);

						if ((bits_set_to_zero != 5) || (bits_set_to_one != 75))
						{
							m_nErrors++;
							m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
								_T("     >>>>> Test %d failed (Count)"), testnumber-1);
						}
					}
				}
			}
		}
	}

	if (bSuccess)
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("     >>>>> Test %d passed"), testnumber-1);
	else
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}

	m_List.AddString(_T(""));

	return testnumber;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// test CXBitArray on 8-bit array
int CXBitArrayTestDlg::RunTest2(CXBitArray& bit, int testnumber)
{
	CString s;
	int i;

	_ASSERTE(bit.GetArraySizeBytes() == 1);

	LPBYTE pBitArray = (LPBYTE) bit;

	//-------------------------------------------------------------------------
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("All bits should be initialized to 1"));

	size_t bits_set_to_zero, bits_set_to_one;
	bit.Count(&bits_set_to_zero, &bits_set_to_one);

	if ((bits_set_to_zero != 0) || (bits_set_to_one != 8))
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed (Count)"), testnumber-1);
	}

	s.Format(_T("pBitArray[0] = %02X:  should be FF"), pBitArray[0]);
	m_List.AddString(s);

	m_List.AddString(_T(""));

	if (pBitArray[0] == 0xFF)
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("     >>>>> Test %d passed"), testnumber-1);
	else
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing Set"));

	m_List.AddString(_T("Setting bits 0 and 7 to 0"));

	bit.Set(0, XBITARRAY_STATUS_USED);
	bit.Set(7, XBITARRAY_STATUS_USED);

	s.Format(_T("pBitArray[0] = %02X:  should be 7E"), pBitArray[0]);
	m_List.AddString(s);

	m_List.AddString(_T(""));

	if (pBitArray[0] != 0x7E)
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}
	else
	{
		m_List.AddString(_T("Setting bits 0 and 7 to 1"));

		bit.Set(0, XBITARRAY_STATUS_FREE);
		bit.Set(7, XBITARRAY_STATUS_FREE);

		s.Format(_T("pBitArray[0] = %02X:  should be FF"), pBitArray[0]);
		m_List.AddString(s);

		m_List.AddString(_T(""));

		if (pBitArray[0] != 0xFF)
		{
			m_nErrors++;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("     >>>>> Test %d failed"), testnumber-1);
		}
		else
			m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
				_T("     >>>>> Test %d passed"), testnumber-1);
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing Get"));
	m_List.AddString(_T(""));

	if (!bit.Get(0))
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}
	else
	{
		if (!bit.Get(7))
		{
			m_nErrors++;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("     >>>>> Test %d failed"), testnumber-1);
		}
		else
		{
			bit.Set(0, XBITARRAY_STATUS_USED);
			bit.Set(7, XBITARRAY_STATUS_USED);

			if (bit.Get(0))
			{
				m_nErrors++;
				m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
					_T("     >>>>> Test %d failed"), testnumber-1);
			}
			else
			{
				if (bit.Get(7))
				{
					m_nErrors++;
					m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
						_T("     >>>>> Test %d failed"), testnumber-1);
				}
				else
					m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
						_T("     >>>>> Test %d passed"), testnumber-1);
			}
		}
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing SetAll"));
	m_List.AddString(_T(""));

	bit.SetAll(0);

	BOOL bSuccess = TRUE;

	for (i = 0; i < 1; i++)
	{
		if (pBitArray[i] != 0)
		{
			bSuccess = FALSE;
			break;
		}
	}

	if (bSuccess)
	{
		bit.SetAll(1);

		for (i = 0; i < 1; i++)
		{
			if (pBitArray[i] != 0xFF)
			{
				bSuccess = FALSE;
				break;
			}
		}
	}

	if (bSuccess)
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("     >>>>> Test %d passed"), testnumber-1);
	else
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing Find"));
	m_List.AddString(_T(""));

	// set all bits to used
	bit.SetAll(XBITARRAY_STATUS_USED);

	bSuccess = TRUE;
	size_t free_pos;

	// testing no free bits
	BOOL rc = bit.Find(0, XBITARRAY_STATUS_FREE, &free_pos);
	if (rc)
		bSuccess = FALSE;

	if (bSuccess)
	{
		// set 1 bit to free
		bit.Set(4, XBITARRAY_STATUS_FREE);

		rc = bit.Find(5, XBITARRAY_STATUS_FREE, &free_pos);	// 5 will force wrap
		if (!rc)
			bSuccess = FALSE;

		if (bSuccess)
		{
			if (free_pos != 4)
			{
				bSuccess = FALSE;
			}
			else
			{
				rc = bit.Find(0, XBITARRAY_STATUS_FREE, &free_pos);
				if (!rc)
					bSuccess = FALSE;

				if (bSuccess)
				{
					if (free_pos != 4)
					{
						bSuccess = FALSE;
					}
					else
					{
						// set all bits to free
						bit.SetAll(XBITARRAY_STATUS_FREE);
						bit.Set(6, XBITARRAY_STATUS_USED);
						rc = bit.Find(7, XBITARRAY_STATUS_USED, &free_pos);
						if (!rc)
							bSuccess = FALSE;
					}
				}
			}
		}
	}

	if (bSuccess)
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("     >>>>> Test %d passed"), testnumber-1);
	else
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}


	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing ToString"));
	m_List.AddString(_T(""));

	// set all bits to used
	bit.SetAll(XBITARRAY_STATUS_FREE);

	// reset every other bit
	bit.Set(0, XBITARRAY_STATUS_USED);
	bit.Set(2, XBITARRAY_STATUS_USED);
	bit.Set(4, XBITARRAY_STATUS_USED);
	bit.Set(6, XBITARRAY_STATUS_USED);

	LPTSTR str = bit.ToString();
	if (str)
	{
		m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
			_T("ToString returned %s, should be 01010101"), str);

		m_List.AddString(_T(""));

		if (_tcscmp(str, _T("01010101")) != 0)
		{
			m_nErrors++;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("     >>>>> Test %d failed"), testnumber-1);
		}
		else
		{
			m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
				_T("     >>>>> Test %d passed"), testnumber-1);
		}
	}
	else
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}

	delete [] str;	// free string allocated by ToString
	str = NULL;

	return testnumber;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int CXBitArrayTestDlg::RunTest3(int testnumber)
{
	BOOL rc = TRUE;

	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing registry persistence"));

	{
		// bit array of 80 bits, allocated from heap, initialized to 1
		CXBitArray bit(ARRAY_SIZE_BYTES*8, 1);

		LPBYTE pBitArray = (LPBYTE) bit;

		m_List.AddString(_T(""));
		m_List.AddString(_T("Setting bits 0 and 79 to 0"));

		bit.Set(0, XBITARRAY_STATUS_USED);
		bit.Set(79, XBITARRAY_STATUS_USED);

		m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
			_T("pBitArray[0] = %02X:  should be FE"), pBitArray[0]);
		m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
			_T("pBitArray[9] = %02X:  should be 7F"), pBitArray[9]);

		m_List.AddString(_T(""));

		if ((pBitArray[0] != 0xFE) || (pBitArray[9] != 0x7F))
		{
			rc = FALSE;
			m_nErrors++;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("     >>>>> Test %d failed"), testnumber-1);
			return testnumber;
		}
		else
		{
			// set registry paths so registry will be written when bit 
			// goes out of scope
			bit.SetRegistryNames(REGISTRY_KEY, REGISTRY_VALUE);
		}
		m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
			_T("==> Writing bit array to:"));
		m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
			_T("        %s\\%s"),
			REGISTRY_KEY, REGISTRY_VALUE);
	}

	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
		_T("==> Reading bit array from:"));
	m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
		_T("        %s\\%s"),
		REGISTRY_KEY, REGISTRY_VALUE);

	// bit array of 80 bits, read from registry
	CXBitArray bit1(REGISTRY_KEY, REGISTRY_VALUE, ARRAY_SIZE_BYTES*8, 1);

	LPBYTE pBitArray1 = (LPBYTE) bit1;

	m_List.AddString(_T(""));

	for (int i = 0; i < 10; i++)
	{
		BYTE value;
		if (i == 0)
			value = 0xFE;
		else if (i == 9)
			value = 0x7F;
		else
			value = 0xFF;

		if (pBitArray1[i] == value)
		{
			m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
				_T("pBitArray1[%d] = %02X:  should be %02X"), 
				i, pBitArray1[i], value);
		}
		else
		{
			m_nErrors++;
			rc = FALSE;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("pBitArray[%d] = %02X:  should be %02X"), 
				i, pBitArray1[i], value);
		}
	}

	m_List.AddString(_T(""));

	if (rc)
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("     >>>>> Test %d passed"), testnumber-1);
	else
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);

	return testnumber;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int CXBitArrayTestDlg::RunTest4(int testnumber)
{
	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing file persistence"));

	{
		// bit array of 80 bits, allocated from heap, initialized to 1
		CXBitArray bit(ARRAY_SIZE_BYTES*8, 1);

		LPBYTE pBitArray = (LPBYTE) bit;

		m_List.AddString(_T(""));
		m_List.AddString(_T("Setting bits 0 and 79 to 0"));

		bit.Set(0, XBITARRAY_STATUS_USED);
		bit.Set(79, XBITARRAY_STATUS_USED);

		m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
			_T("pBitArray[0] = %02X:  should be FE"), pBitArray[0]);
		m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
			_T("pBitArray[9] = %02X:  should be 7F"), pBitArray[9]);

		m_List.AddString(_T(""));

		if ((pBitArray[0] != 0xFE) || (pBitArray[9] != 0x7F))
		{
			m_nErrors++;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("     >>>>> Test %d failed"), testnumber-1);
			return testnumber;
		}
		else
		{
			// set file path so file will be written when bit 
			// goes out of scope
			bit.SetPersistFileName(TEST_FILE);
		}
		m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
			_T("==> Writing bit array to %s"), TEST_FILE);
	}

	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
		_T("==> Reading bit array from %s"), TEST_FILE);

	// bit array of 80 bits, read from file
	CXBitArray bit1(TEST_FILE, ARRAY_SIZE_BYTES*8, 1);

	LPBYTE pBitArray1 = (LPBYTE) bit1;

	m_List.AddString(_T(""));

	BOOL rc = TRUE;

	for (int i = 0; i < 10; i++)
	{
		BYTE value;
		if (i == 0)
			value = 0xFE;
		else if (i == 9)
			value = 0x7F;
		else
			value = 0xFF;

		if (pBitArray1[i] == value)
		{
			m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
				_T("pBitArray1[%d] = %02X:  should be %02X"), 
				i, pBitArray1[i], value);
		}
		else
		{
			m_nErrors++;
			rc = FALSE;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("pBitArray1[%d] = %02X:  should be %02X"), 
				i, pBitArray1[i], value);
		}
	}

	m_List.AddString(_T(""));

	if (rc)
		m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
			_T("     >>>>> Test %d passed"), testnumber-1);
	else
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);

	return testnumber;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int CXBitArrayTestDlg::RunTest5(int testnumber)
{
	//-------------------------------------------------------------------------
	m_List.AddString(_T(""));
	m_List.Printf(CXListBox::Blue, CXListBox::White, 0, 
		_T("========== Test %d =========="), testnumber++);

	m_List.AddString(_T(""));
	m_List.AddString(_T("Testing Attach"));

	BYTE barray[ARRAY_SIZE_BYTES];
	ZeroMemory(barray, ARRAY_SIZE_BYTES);
	barray[0] = 0x11;	// set some bits

	// uninitialized bit array
	CXBitArray bit;
	bit.Attach(barray, ARRAY_SIZE_BYTES*8);

	LPBYTE pBitArray = (LPBYTE) bit;

	m_List.AddString(_T(""));

	m_List.AddString(_T("Testing bits 0 and 4"));

	m_List.Printf(CXListBox::Black, CXListBox::White, 0, 
		_T("pBitArray[0] = %02X:  should be 11"), pBitArray[0]);

	m_List.AddString(_T(""));

	if (pBitArray[0] != 0x11)
	{
		m_nErrors++;
		m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
			_T("     >>>>> Test %d failed"), testnumber-1);
	}
	else
	{
		if (bit.Get(0) == 0 || bit.Get(4) == 0)
		{
			m_nErrors++;
			m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
				_T("     >>>>> Test %d failed"), testnumber-1);
		}
		else
		{
			size_t bits_set_to_zero, bits_set_to_one;
			bit.Count(&bits_set_to_zero, &bits_set_to_one);

			if ((bits_set_to_zero != 78) || (bits_set_to_one != 2))
			{
				m_nErrors++;
				m_List.Printf(CXListBox::Red, CXListBox::White, 0, 
					_T("     >>>>> Test %d failed (Count)"), testnumber-1);
			}
			else
			{
				m_List.Printf(CXListBox::Green, CXListBox::White, 0, 
					_T("     >>>>> Test %d passed"), testnumber-1);
			}
		}
	}

	return testnumber;
}


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void CXBitArrayTestDlg::CreateBitFile(LPCTSTR lpszFile, 
									  DWORD dwSizeBytes, 
									  BOOL bit_value)
{
	_ASSERTE(lpszFile);
	_ASSERTE(lpszFile[0] != _T('\0'));
	_ASSERTE(dwSizeBytes > 0);

	if (dwSizeBytes == 0)
	{
		TRACE(_T("ERROR:  dwSizeBytes is 0\n"));
		return;
	}

	if (!lpszFile || lpszFile[0] == _T('\0'))
	{
		TRACE(_T("ERROR:  lpszFile is NULL\n"));
		return;
	}

	HANDLE hFile = INVALID_HANDLE_VALUE;
	hFile = ::CreateFile(lpszFile,
						 GENERIC_READ | GENERIC_WRITE,
						 FILE_SHARE_READ | FILE_SHARE_WRITE,
						 NULL,
						 CREATE_ALWAYS,
						 FILE_ATTRIBUTE_NORMAL,
						 NULL);

	if (hFile == INVALID_HANDLE_VALUE)
	{
		TRACE(_T("ERROR: CreateFile failed for %s\n"), lpszFile);
	}
	else
	{
		BYTE * pBuf = new BYTE [dwSizeBytes];

		BYTE value = 0;

		if (bit_value)
			value = 0xFF;

		for (size_t i = 0; i < dwSizeBytes; i++)
			pBuf[i] = value;

		DWORD dwBytesWritten = 0;

		BOOL bRet = ::WriteFile(hFile, 
								(LPVOID) pBuf, 
								dwSizeBytes, 
								&dwBytesWritten, 
								NULL);

		_ASSERTE(bRet);
		::FlushFileBuffers(hFile);
		::CloseHandle(hFile);

		if (pBuf)
			delete [] pBuf;
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Hans Dietrich Software
United States United States
I attended St. Michael's College of the University of Toronto, with the intention of becoming a priest. A friend in the University's Computer Science Department got me interested in programming, and I have been hooked ever since.

Recently, I have moved to Los Angeles where I am doing consulting and development work.

For consulting and custom software development, please see www.hdsoft.org.






Comments and Discussions