// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: testprog.cpp
// Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC
// Produced By: glNET Software
// File Creation Date: 04/05/1996
// Date Last Modified: 05/25/2001
// Copyright (c) 2001 glNET Software
// ----------------------------------------------------------- //
// ------------- Program Description and Details ------------- //
// ----------------------------------------------------------- //
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
Doubly linked list class test program.
*/
// ----------------------------------------------------------- //
#include <iostream.h>
#include <string.h>
#include "gxlistb.h"
#ifdef __MSVC_DEBUG__
#include "leaktest.h"
#endif
void PausePrg()
{
// PausePrg the program until enter is pressed
cout << endl;
cout << "Press Enter to continue...\n";
cin.get();
}
void ScrollForward(gxListB &list)
{
cout << "Walking through the list..." << endl;
gxListNodeB *ptr = list.GetHead();
while(ptr) {
int val = (int)ptr->data;
cout << (char)val << ' ';
ptr = ptr->next;
}
cout << endl;
}
void RewindList(gxListB &list)
{
cout << "Walking through the list in a backward direction..." << endl;
gxListNodeB *ptr = list.GetTail();
// Walk through the list in a backward direction
while(ptr) {
int val = (int)ptr->data;
cout << (char)val << ' ';
ptr = ptr->prev;
}
cout << endl;
}
int main()
{
#ifdef __MSVC_DEBUG__
InitLeakTest();
#endif
gxListB list;
gxListNodeB *ptr;
// Consturct some list nodes
cout << "Loading data elements into linked list..." << endl;
gxListNodeB *na = new gxListNodeB;
gxListNodeB *nb = new gxListNodeB;
gxListNodeB *nc = new gxListNodeB;
gxListNodeB *nd = new gxListNodeB;
gxListNodeB *n1 = new gxListNodeB;
gxListNodeB *n2 = new gxListNodeB;
gxListNodeB *n3 = new gxListNodeB;
gxListNodeB *n4 = new gxListNodeB;
// Statically allocated list data
const unsigned num_blocks = 9;
char buf[num_blocks];
unsigned i;
// Load some values into the buffer starting with ASCII character 'A'
for(i = 0; i < num_blocks; i++) buf[i] = (char)(65+i);
na->data = (void *)buf[0];
nb->data = (void *)buf[1];
nc->data = (void *)buf[2];
nd->data = (void *)buf[3];
// Load some list elements
list.InsertAfter(list.GetHead(), na);
list.InsertAfter(na, nb);
list.InsertAfter(nb, nc);
list.InsertAfter(nc, nd);
n1->data = (void *)buf[4];
n2->data = (void *)buf[5];
n3->data = (void *)buf[6];
n4->data = (void *)buf[7];
// Testing insert functions
list.InsertBefore(na, n1);
list.InsertBefore(nc, n2);
list.InsertAfter(nb, n3);
list.InsertAfter(nd, n4);
// Reordering the list
list.MoveToBack(na);
list.MoveAfter(na, nc);
list.MoveBefore(nc, nb);
list.MoveAfter(nc, nd);
list.MoveAfter(nd, n2);
list.MoveBefore(n2, n1);
list.MoveAfter(n2, n3);
list.MoveAfter(n3, n4);
ScrollForward(list);
RewindList(list);
PausePrg();
cout << "Adding another item to the list..." << endl;
ptr = list.Add((void *)buf[8]);
ScrollForward(list);
PausePrg();
cout << "Moving list item to the front of the list" << endl;
list.MoveToFront(ptr);
ScrollForward(list);
cout << "Moving item to the back of the list..." << endl;
list.MoveToBack(ptr);
ScrollForward(list);
PausePrg();
cout << "Removing the head of the list..." << endl;
ptr = list.GetHead();
list.Remove(ptr);
ScrollForward(list);
cout << "Removing the tail of the list..." << endl;
ptr = list.GetTail();
list.Remove(ptr);
ScrollForward(list);
// NOTE: A gxListB::ClearList() call is used here to free the memory
// allocated for the node since the node data was statically allocated.
list.ClearList();
PausePrg();
cout << "Testing for memory leaks..." << endl;
const char *test_str = "The quick brown fox jumps over the lazy dog";
unsigned len = strlen(test_str);
const unsigned num_to_allocate = 10 * 100; // 1000 * 1000;
const unsigned mem_bufs = (sizeof(gxListNodeB) + len) * num_to_allocate;
cout << "Allocating " << mem_bufs << " bytes..." << endl;
unsigned count1 = 0;
unsigned count2 = 0;
for(i = 0; i < num_to_allocate; i++) {
char *sbuf = new char[len+1]; // Allocate memory for the string
count1 += sizeof(sbuf);
if(!sbuf) {
cout << "Memory allocation error at " << (count1+count2) << " bytes"
<< endl;
break;
}
memmove(sbuf, test_str, len);
sbuf[len] = 0; // Null terminate the string
count2 += sizeof(gxListNodeB);
if(!list.Add((void *)sbuf)) {
cout << "Memory allocation error at " << (count1+count2) << " bytes"
<< endl;
break;
}
}
cout << "Done" << endl;
PausePrg();
cout << "Releasing memory allocated back to the heap..." << endl;
// NOTE: A gxListB::DestroyList() call will free the memory allocated for
// both the node and its data.
list.DestroyList();
PausePrg();
cout << "Exiting..." << endl;
cout << endl;
return 0;
}
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //