Object-oriented Programming and the KWIC system---Part 2

Review the declaration for the List class template

Emphasis: handles lists of objects derived from Node.

Overview of LineStorage changes

LineStorage.C

/********** LineStorage module---implementation **********/

#include <string.h>
#include <iostream.h>
#include <stdlib.h>
#include "kwic.h"
#include "LineStorage.h"
#include "List.h"

/***** local constants *****/

/***** local types *****/

class WordNode : public Node {
public:
	WordNode() { word = 0; }
	~WordNode() { delete word; }
	char *word;
};
typedef List<WordNode> WordList;

class LineNode : public Node {
public:
	WordList wordList;
};
typedef List<LineNode> LineList;

/***** local variables *****/

static LineList lineList;

/***** state invariant *****

1. For every WordNode allocated
	word is a null-terminated array of characters.

2. All of the LineNodes and WordNodes allocated by LineStorage
   (and not yet deleted) are in lineList.
*/

/***** local functions *****/

/***** exported functions *****/

void LSInit(void)
{
	// intentionally empty
}

void LSReset(void)
{
	LineNode* lineNodePtr;
	WordNode* wordNodePtr;

	while (lineNodePtr = lineList.remove()) {
		while (wordNodePtr = lineNodePtr->wordList.remove()) {
			delete wordNodePtr;
		}
		delete lineNodePtr;
	}
}

KWStatus LSAddLine(void)
{
	LineNode* newPtr = new LineNode;
	if (newPtr == 0)
		return KWMEMORYERROR;

	lineList.add(newPtr);
	return KWSUCCESS;
}

KWStatus LSAddWord(char* word)
{

	if (lineList.size() == 0)
		return KWRANGEERROR;

	/* create and fill a WordNode */
	WordNode* wordNodePtr = new WordNode;
	if (wordNodePtr == 0)
		return KWMEMORYERROR;
	wordNodePtr->word = new char [(strlen(word)+1)];
	if (wordNodePtr->word == 0) {
		delete wordNodePtr;
		return KWMEMORYERROR;
	}
	strcpy(wordNodePtr->word,word);
	lineList[lineList.size()-1]->wordList.add(wordNodePtr);

	return KWSUCCESS;
}

const char* LSGetWord(int lineNum,int wordNum)
{
	if (lineNum < 0 || lineNum >= lineList.size())
		return 0;
	
	WordNode* wordNodePtr = lineList[lineNum]->wordList[wordNum];
	return wordNodePtr == 0 ? 0 : wordNodePtr->word;
}

int LSNumWords(int lineNum)
{
	LineNode* tmpPtr = lineList[lineNum];
	return tmpPtr == 0 ? KWRANGEERROR : tmpPtr->wordList.size();
}

int LSNumLines(void)
{
	return lineList.size();
}

void LSPrintState(void)
{
	int lineListSize = lineList.size();
	cout << "lineList size: " << lineListSize << endl;
	for (int i = 0; i < lineListSize; i++) {
		LineNode* lineNodePtr = lineList[i];
		int wordListSize = lineNodePtr->wordList.size();
		cout << "wordList size: " << wordListSize << endl << "\t";
		for (int j = 0; j < wordListSize; j++) {
			cout << "!" << lineNodePtr->wordList[j]->word;
		}
		cout << "!" << endl;
	}
}